Blaze3D API Reference
Blaze3D API Reference
Section titled “Blaze3D API Reference”Blaze3D is Minecraft 26.1’s graphics abstraction layer that provides a clean interface between game code and graphics APIs. This reference covers all major Blaze3D classes, methods, and usage patterns.
Core Classes
Section titled “Core Classes”Blaze3D
Section titled “Blaze3D”The main entry point for Blaze3D functionality.
public final class Blaze3D { private Blaze3D() { // Private constructor - utility class }
/** * Returns the current time in milliseconds since startup. * Used for animation timing and effects. */ public static long getTime() { return System.nanoTime() / 1000000L; }
/** * Easter egg method - displays game over message. * Not typically used in modding. */ public static String youJustLostTheGame() { return new Random().nextFloat() < 0.025F ? "You just lost The Game!" : null; }}Usage Example:
// Example: Animation timing using Blaze3Dpublic void renderAnimatedEffect(float partialTick) { long currentTime = Blaze3D.getTime(); float animationTime = (currentTime % 2000L) / 1000.0f; float pulseValue = (float) Math.sin(animationTime * Math.PI);
// Use pulse value for visual effects setEffectIntensity(pulseValue);}RenderSystem
Section titled “RenderSystem”The central coordinator for all rendering operations and state management.
public final class RenderSystem { private static final Thread MAIN_RENDER_THREAD = Thread.currentThread(); private static GpuDevice device;
/** * Checks if the current thread is the render thread. * All rendering operations must be called from the render thread. */ public static boolean isOnRenderThread() { return Thread.currentThread() == MAIN_RENDER_THREAD; }
/** * Throws IllegalStateException if not on render thread. * Used for debugging and ensuring thread safety. */ public static void assertOnRenderThread() { if (!isOnRenderThread()) { throw new IllegalStateException("Not on render thread"); } }
/** * Gets the current graphics device instance. * Used to create GPU resources. */ public static GpuDevice getDevice() { if (device == null) { device = createGpuDevice(); } return device; }
/** * Sets up the projection matrix for 2D GUI rendering. * @param width Screen width * @param height Screen height */ public static void setProjectionGui(int width, int height) { Matrix4f matrix = new Matrix4f(); matrix.setOrthographic(0.0F, width, height, 0.0F, 2000.0F); setProjectionMatrix(matrix); }
/** * Applies a translation transformation to the current matrix stack. * @param x X offset * @param y Y offset * @param z Z offset */ public static void translatef(double x, double y, double z) { RenderSystem.assertOnRenderThread(); getMatrixStack().translate(x, y, z); }
/** * Applies a rotation transformation around an axis. * @param angle Rotation angle in degrees * @param x X component of rotation axis * @param y Y component of rotation axis * @param z Z component of rotation axis */ public static void rotatef(float angle, float x, float y, float z) { RenderSystem.assertOnRenderThread(); getMatrixStack().mulPose(Axis.of(new Vec3(x, y, z)).rotationDegrees(angle)); }
/** * Applies a scale transformation. * @param x X scale factor * @param y Y scale factor * @param z Z scale factor */ public static void scalef(float x, float y, float z) { RenderSystem.assertOnRenderThread(); getMatrixStack().scale(x, y, z); }
/** * Sets the current shader for rendering operations. * @param shader Supplier that provides the shader instance */ public static void setShader(Supplier<ShaderInstance> shader) { RenderSystem.assertOnRenderThread(); ShaderInstance instance = shader.get(); if (instance != null) { instance.apply(); } }
/** * Sets shader color multiplier. * @param r Red component (0-1) * @param g Green component (0-1) * @param b Blue component (0-1) * @param a Alpha component (0-1) */ public static void setShaderColor(float r, float g, float b, float a) { RenderSystem.assertOnRenderThread(); ShaderInstance shader = getInstance().getShader(); if (shader != null) { shader.safeGetUniform("Color").set(r, g, b, a); } }}Usage Examples:
// Example: Safe rendering with proper state managementpublic void renderCustomGeometry() { RenderSystem.assertOnRenderThread();
// Save current state RenderSystem.pushMatrix();
// Apply transformations RenderSystem.translatef(x, y, z); RenderSystem.rotatef(angle, 0.0F, 1.0F, 0.0F); RenderSystem.scalef(scale, scale, scale);
// Set shader and color RenderSystem.setShader(GameRenderer::getPositionColorShader); RenderSystem.setShaderColor(1.0F, 1.0F, 1.0F, 1.0F);
// Render geometry renderGeometry();
// Restore state RenderSystem.popMatrix();}
// Example: Thread-safe operationpublic void scheduleRenderOperation(Runnable operation) { if (RenderSystem.isOnRenderThread()) { operation.run(); } else { Minecraft.getInstance().execute(operation); }}Device Interface
Section titled “Device Interface”GpuDevice
Section titled “GpuDevice”Abstract interface for GPU device operations.
public interface GpuDevice {
/** * Creates a GPU buffer with specified type and usage flags. * @param type Buffer type (VERTEX, INDEX, UNIFORM, etc.) * @param usage Usage flags (MAP_READ, MAP_WRITE, etc.) * @return New GPU buffer instance */ GpuBuffer createBuffer(GpuBuffer.BufferType type, long usage);
/** * Creates a GPU texture with specified properties. * @param type Texture type (TEXTURE_2D, TEXTURE_CUBE_MAP, etc.) * @param width Texture width in pixels * @param height Texture height in pixels * @param usage Usage flags (TEXTURE_BINDING, RENDER_ATTACHMENT, etc.) * @return New GPU texture instance */ GpuTexture createTexture(GpuTexture.TextureType type, int width, int height, long usage);
/** * Creates a texture sampler with specified properties. * @param wrapU U-axis wrap mode * @param wrapV V-axis wrap mode * @param minFilter Minification filter * @param magFilter Magnification filter * @return New sampler instance */ GpuSampler createSampler(GpuSampler.WrapMode wrapU, GpuSampler.WrapMode wrapV, GpuSampler.MinFilter minFilter, GpuSampler.MagFilter magFilter);
/** * Compiles and creates a shader from specified sources. * @param name Shader identifier * @param vertexSource Vertex shader source code * @param fragmentSource Fragment shader source code * @return Compiled shader instance */ ShaderInstance compileShader(String name, String vertexSource, String fragmentSource);
/** * Executes a task with GPU synchronization. * @param fence Fence for synchronization * @param task Task to execute */ void queueFencedTask(GpuFence fence, Runnable task);
/** * Returns device capabilities and features. * @return Device capabilities object */ DeviceCapabilities getCapabilities();}Usage Example:
// Example: Creating GPU resources through devicepublic class ResourceCreator { private final GpuDevice device; private GpuBuffer vertexBuffer; private GpuTexture texture; private GpuSampler sampler;
public ResourceCreator() { this.device = RenderSystem.getDevice(); }
public void createResources() { RenderSystem.assertOnRenderThread();
// Create vertex buffer this.vertexBuffer = device.createBuffer( GpuBuffer.BufferType.VERTEX, GpuBuffer.Usage.STATIC_DRAW );
// Create texture this.texture = device.createTexture( GpuTexture.TextureType.TEXTURE_2D, 256, 256, GpuTexture.Usage.TEXTURE_BINDING | GpuTexture.Usage.COPY_SRC );
// Create sampler this.sampler = device.createSampler( GpuSampler.WrapMode.REPEAT, GpuSampler.WrapMode.REPEAT, GpuSampler.MinFilter.LINEAR, GpuSampler.MagFilter.LINEAR );
// Upload data to resources uploadResourceData(); }}Buffer Management
Section titled “Buffer Management”GpuBuffer
Section titled “GpuBuffer”Abstract base class for GPU memory buffers.
public abstract class GpuBuffer implements AutoCloseable { public enum BufferType { VERTEX, // Vertex data buffer INDEX, // Index data buffer UNIFORM, // Uniform data buffer STORAGE // Storage buffer (if supported) }
public enum UsageFlag { MAP_READ(1L), // Buffer can be read by CPU MAP_WRITE(2L), // Buffer can be written by CPU COPY_SRC(4L), // Buffer can be copy source COPY_DST(8L), // Buffer can be copy destination VERTEX(16L), // Buffer can be vertex binding INDEX(32L), // Buffer can be index binding UNIFORM(64L); // Buffer can be uniform binding
public final long mask; UsageFlag(long mask) { this.mask = mask; } }
/** * Binds this buffer to the specified binding point. * @param binding Binding point index */ public abstract void bind(int binding);
/** * Unbinds this buffer from the current binding point. */ public abstract void unbind();
/** * Uploads data to this buffer. * @param data Byte buffer containing data to upload */ public abstract void upload(ByteBuffer data);
/** * Uploads a portion of data to this buffer. * @param offset Offset in bytes from buffer start * @param data Byte buffer containing data to upload */ public abstract void upload(long offset, ByteBuffer data);
/** * Creates a slice view into this buffer. * @param offset Offset in bytes from buffer start * @param length Length of slice in bytes * @return Buffer slice view */ public abstract GpuBufferSlice slice(long offset, long length);
/** * Maps this buffer for CPU access. * @param access Access mode (READ_ONLY, WRITE_ONLY, READ_WRITE) * @return Mapped memory buffer */ public abstract ByteBuffer map(GpuBuffer.MapAccess access);
/** * Unmaps this buffer from CPU access. */ public abstract void unmap();
/** * Gets the size of this buffer in bytes. * @return Buffer size */ public abstract long getSize();
/** * Closes and releases this buffer's GPU resources. */ public abstract void close();}Usage Example:
// Example: Creating and using a vertex bufferpublic class VertexBufferExample { private GpuBuffer vertexBuffer; private final GpuDevice device;
public VertexBufferExample() { this.device = RenderSystem.getDevice(); }
public void createVertexBuffer(float[] vertices) { RenderSystem.assertOnRenderThread();
// Create buffer with appropriate usage flags this.vertexBuffer = device.createBuffer( GpuBuffer.BufferType.VERTEX, GpuBuffer.Usage.STATIC_DRAW | GpuBuffer.Usage.MAP_WRITE );
// Convert float array to byte buffer ByteBuffer byteBuffer = BufferUtils.createFloatBuffer(vertices.length); byteBuffer.asFloatBuffer().put(vertices).flip();
// Upload data vertexBuffer.upload(byteBuffer); }
public void renderBuffer() { RenderSystem.assertOnRenderThread();
// Bind buffer for drawing vertexBuffer.bind();
// Issue draw call int vertexCount = (int)(vertexBuffer.getSize() / (6 * Float.BYTES)); // 6 floats per vertex GL11.glDrawArrays(GL11.GL_QUADS, 0, vertexCount);
// Unbind vertexBuffer.unbind(); }
public void cleanup() { if (vertexBuffer != null) { vertexBuffer.close(); } }}BufferBuilder
Section titled “BufferBuilder”High-performance vertex data construction utility.
public class BufferBuilder { private final VertexFormat format; private ByteBuffer buffer; private int vertexCount; private boolean building;
/** * Begins vertex data construction with specified format and mode. * @param mode Drawing mode (QUADS, TRIANGLES, LINES, etc.) * @param format Vertex data format */ public void begin(VertexFormat.Mode mode, VertexFormat format) { if (this.building) { throw new IllegalStateException("Already building"); }
this.mode = mode; this.format = format; this.vertexCount = 0; this.buffer = MemoryUtil.malloc(this.format.getVertexSize() * 65536); this.building = true; }
/** * Adds a vertex with position data. * @param x X coordinate * @param y Y coordinate * @param z Z coordinate * @return BufferBuilder for chaining */ public BufferBuilder vertex(float x, float y, float z) { if (!this.building) { throw new IllegalStateException("Not building"); }
ensureCapacity(this.format.getVertexSize()); writePosition(x, y, z); return this; }
/** * Adds color data to current vertex. * @param r Red component (0-255) * @param g Green component (0-255) * @param b Blue component (0-255) * @param a Alpha component (0-255) * @return BufferBuilder for chaining */ public BufferBuilder color(int r, int g, int b, int a) { if (!this.building) { throw new IllegalStateException("Not building"); }
writeColor(r, g, b, a); return this; }
/** * Adds texture coordinate data to current vertex. * @param u U coordinate * @param v V coordinate * @return BufferBuilder for chaining */ public BufferBuilder uv(float u, float v) { if (!this.building) { throw new IllegalStateException("Not building"); }
writeUv(u, v); return this; }
/** * Ends vertex data construction and returns result. * @return RenderedBuffer containing vertex data */ public RenderedBuffer end() { if (!this.building) { throw new IllegalStateException("Not building"); }
this.building = false;
// Create final buffer with actual used size ByteBuffer finalBuffer = MemoryUtil.malloc(this.buffer.position()); this.buffer.flip(); finalBuffer.put(this.buffer); finalBuffer.flip();
return new RenderedBuffer(finalBuffer, this.vertexCount); }
private static class RenderedBuffer { public final ByteBuffer vertexBuffer; public final int vertexCount;
RenderedBuffer(ByteBuffer vertexBuffer, int vertexCount) { this.vertexBuffer = vertexBuffer; this.vertexCount = vertexCount; } }}Usage Example:
// Example: Building complex geometry with BufferBuilderpublic BufferBuilder.RenderedBuffer createCubeGeometry() { BufferBuilder builder = new BufferBuilder(256);
builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR_TEX);
// Front face builder.vertex(-0.5f, -0.5f, 0.5f) .color(255, 255, 255, 255) .uv(0.0f, 0.0f) .endVertex();
builder.vertex(0.5f, -0.5f, 0.5f) .color(255, 255, 255, 255) .uv(1.0f, 0.0f) .endVertex();
builder.vertex(0.5f, 0.5f, 0.5f) .color(255, 255, 255, 255) .uv(1.0f, 1.0f) .endVertex();
builder.vertex(-0.5f, 0.5f, 0.5f) .color(255, 255, 255, 255) .uv(0.0f, 1.0f) .endVertex();
// Add remaining faces...
return builder.end();}Texture Management
Section titled “Texture Management”GpuTexture
Section titled “GpuTexture”Abstract base class for GPU texture resources.
public abstract class GpuTexture implements AutoCloseable { public enum TextureType { TEXTURE_1D, // 1D texture TEXTURE_2D, // 2D texture (most common) TEXTURE_3D, // 3D texture TEXTURE_CUBE_MAP, // Cube map texture TEXTURE_1D_ARRAY, // 1D texture array TEXTURE_2D_ARRAY, // 2D texture array TEXTURE_CUBE_MAP_ARRAY // Cube map array }
public enum UsageFlag { COPY_SRC(1L), // Texture can be copy source COPY_DST(2L), // Texture can be copy destination TEXTURE_BINDING(4L), // Texture can be bound for sampling RENDER_ATTACHMENT(8L), // Texture can be render target CUBEMAP_COMPATIBLE(16L); // Texture can be used as cube map
public final long mask; UsageFlag(long mask) { this.mask = mask; } }
/** * Uploads image data to this texture. * @param level Mipmap level (0 for base level) * @param x X offset in pixels * @param y Y offset in pixels * @param width Image width in pixels * @param height Image height in pixels * @param format Pixel format * @param buffer Image data buffer */ public abstract void upload(int level, int x, int y, int width, int height, TextureFormat format, ByteBuffer buffer);
/** * Creates a view into this texture. * @param level Mipmap level * @param layer Array layer or cube face * @return Texture view */ public abstract GpuTextureView createView(int level, int layer);
/** * Binds this texture to the specified texture unit. * @param unit Texture unit index */ public abstract void bind(int unit);
/** * Unbinds this texture. */ public abstract void unbind();
/** * Generates mipmaps for this texture. */ public abstract void generateMipmaps();
/** * Gets the texture width. * @return Width in pixels */ public abstract int getWidth();
/** * Gets the texture height. * @return Height in pixels */ public abstract int getHeight();
/** * Closes and releases this texture's GPU resources. */ public abstract void close();}Usage Example:
// Example: Creating and using texturespublic class TextureManager { private final Map<String, GpuTexture> textures = new HashMap<>(); private final GpuDevice device;
public TextureManager() { this.device = RenderSystem.getDevice(); }
public void loadTexture(String name, BufferedImage image) { RenderSystem.assertOnRenderThread();
// Convert image to byte buffer ByteBuffer buffer = convertImageToBuffer(image);
// Create texture GpuTexture texture = device.createTexture( GpuTexture.TextureType.TEXTURE_2D, image.getWidth(), image.getHeight(), GpuTexture.Usage.TEXTURE_BINDING | GpuTexture.Usage.COPY_SRC );
// Upload image data texture.upload(0, 0, 0, image.getWidth(), image.getHeight(), TextureFormat.RGBA, buffer);
// Generate mipmaps texture.generateMipmaps();
this.textures.put(name, texture); }
public void bindTexture(String name, int unit) { GpuTexture texture = textures.get(name); if (texture != null) { texture.bind(unit); } }
public void cleanup() { for (GpuTexture texture : textures.values()) { texture.close(); } textures.clear(); }}Common Patterns
Section titled “Common Patterns”Resource Management
Section titled “Resource Management”// Example: RAII pattern for automatic resource cleanuppublic class ScopedResource implements AutoCloseable { private final GpuBuffer buffer; private final GpuTexture texture;
public ScopedResource() { this.buffer = RenderSystem.getDevice().createBuffer( GpuBuffer.BufferType.VERTEX, GpuBuffer.Usage.STATIC_DRAW); this.texture = RenderSystem.getDevice().createTexture( GpuTexture.TextureType.TEXTURE_2D, 256, 256, GpuTexture.Usage.TEXTURE_BINDING); }
public GpuBuffer getBuffer() { return buffer; } public GpuTexture getTexture() { return texture; }
@Override public void close() { if (buffer != null) buffer.close(); if (texture != null) texture.close(); }}
// Usage with try-with-resourcespublic void renderWithScopedResources() { RenderSystem.assertOnRenderThread();
try (ScopedResource resources = new ScopedResource()) { // Use resources resources.getTexture().bind(0); resources.getBuffer().bind();
// Perform rendering renderGeometry(); } // Resources automatically cleaned up}Thread Safety
Section titled “Thread Safety”// Example: Safe asynchronous resource creationpublic class AsyncResourceCreator { private CompletableFuture<GpuBuffer> bufferFuture;
public void createBufferAsync(float[] vertexData) { // Convert to byte buffer on current thread ByteBuffer byteBuffer = BufferUtils.createFloatBuffer(vertexData.length); byteBuffer.asFloatBuffer().put(vertexData).flip();
// Schedule GPU resource creation on render thread this.bufferFuture = CompletableFuture.supplyAsync(() -> { GpuDevice device = RenderSystem.getDevice(); GpuBuffer buffer = device.createBuffer( GpuBuffer.BufferType.VERTEX, GpuBuffer.Usage.STATIC_DRAW); buffer.upload(byteBuffer); return buffer; }, Minecraft.getInstance()); }
public void whenReady(Consumer<GpuBuffer> callback) { bufferFuture.thenAcceptAsync(callback, Minecraft.getInstance()); }}Performance Considerations
Section titled “Performance Considerations”Buffer Pooling
Section titled “Buffer Pooling”// Example: Buffer pool for reducing allocationspublic class BufferPool { private final Queue<GpuBuffer> availableBuffers = new ArrayDeque<>(); private final GpuDevice device; private final int bufferSize;
public BufferPool(GpuDevice device, int bufferSize) { this.device = device; this.bufferSize = bufferSize; }
public GpuBuffer acquire() { RenderSystem.assertOnRenderThread();
GpuBuffer buffer = availableBuffers.poll(); if (buffer == null) { buffer = device.createBuffer( GpuBuffer.BufferType.VERTEX, GpuBuffer.Usage.DYNAMIC_DRAW); } return buffer; }
public void release(GpuBuffer buffer) { RenderSystem.assertOnRenderThread();
if (availableBuffers.size() < 16) { // Limit pool size availableBuffers.offer(buffer); } else { buffer.close(); } }
public void cleanup() { RenderSystem.assertOnRenderThread();
for (GpuBuffer buffer : availableBuffers) { buffer.close(); } availableBuffers.clear(); }}Common Issues and Solutions
Section titled “Common Issues and Solutions”Resource Leaks
Section titled “Resource Leaks”Problem: Memory usage increases over time Solution: Use proper resource management patterns and RAII
Thread Safety Violations
Section titled “Thread Safety Violations”Problem: Crashes due to non-render thread operations
Solution: Always use RenderSystem.assertOnRenderThread() and proper synchronization
Performance Bottlenecks
Section titled “Performance Bottlenecks”Problem: Excessive buffer allocations Solution: Use buffer pooling and reuse resources
Best Practices
Section titled “Best Practices”- Always check thread safety before using RenderSystem
- Use RAII patterns for automatic resource cleanup
- Pool buffers for frequently allocated resources
- Validate bounds when using buffer slices
- Cache resource references to avoid repeated lookups
- Profile GPU operations to identify bottlenecks
Related Classes
Section titled “Related Classes”- Buffer Management Guide - Practical buffer usage patterns
- Render Types Reference - Render type configurations
- Shader Pipeline Reference - Shader management and compilation
- Getting Started with Blaze3D - Blaze3D concepts and overview