Class MdiBatchCoordinator

java.lang.Object
com.hbm_m.client.render.MdiBatchCoordinator

public final class MdiBatchCoordinator extends Object
Optional Multi-Draw Indirect aggregation path for InstancedStaticPartRenderer.

Today each InstancedStaticPartRenderer.flushBatchVanilla issues one glDrawElementsInstanced call. A typical machine BER drives 8-11 part renderers, so the per-frame draw call count on the vanilla path scales as partsPerMachine. When all part renderers share the same vertex format (pos vec3 / normal vec3 / uv vec2, stride 32) AND the same legacy (unsliced) per-instance layout (loc 3..11), we can collapse those into one indirect-command buffer + либо цикл glDrawElementsIndirect, либо (опционально) один glMultiDrawElementsIndirect — общий атлас VAO и единый per-instance VBO.

Fallback chain (in order):

  1. hasDrawIndirect && hasBaseInstance (GL 4.0+ draw indirect + base instance в команде): путь атласа; один glMultiDrawElementsIndirect на flush.
  2. Otherwise: legacy per-renderer glDrawElementsInstanced (the flushBatchVanilla path stays as-is).

Eligibility constraints for an individual flush:

  • Iris/Oculus NOT active (we only optimise the vanilla shader path).
  • Unsliced light layout (useSlicedLight == false). Sliced parts use a different attribute layout (loc 7..14 + 15) and a different shader, so they fall through to the legacy path.
  • Renderer initialised, instanceCount > 0.
  • ModClothConfig.useMultiDrawIndirect enabled.

Iris path: untouched. InstancedStaticPartRenderer.flush(Matrix4f) still routes to flushBatchIris when an external shader is active — the coordinator's eligibility test rejects those flushes up front.

  • Method Details

    • refreshProjection

      public void refreshProjection(org.joml.Matrix4f projection)
      Latest projection from the render event (camera may move within a game tick).
    • ensureCapsResolved

      public static void ensureCapsResolved()
    • isMdiAvailable

      public static boolean isMdiAvailable()
    • beginFrame

      public static MdiBatchCoordinator beginFrame(org.joml.Matrix4f projectionMatrix)
    • active

      public static MdiBatchCoordinator active()
    • discardActiveSessionNoDispatch

      public static void discardActiveSessionNoDispatch()
      Сброс активной MDI-сессии без dispatch() — при F3+T / очистке GPU-кэшей, когда кадр уже не должен бить в атлас (см. MdiGeometryAtlas.resetForResourceLifecycle()).
    • endFrame

      public void endFrame()
    • endFrame

      public void endFrame(boolean deferDraw)
      Finishes accumulation for a game tick. When deferDraw, uploads instance data and replaces scheduledDraw — only the last deferred batch is drawn per render frame.
    • presentScheduledDraw

      public static void presentScheduledDraw(org.joml.Matrix4f projection)
      GL draw for the scheduled batch. Call at start of a new client render frame (first AFTER_ENTITIES), not AFTER_LEVEL — dirty texture units after level end.
    • cancelScheduledDraw

      public static void cancelScheduledDraw()
    • clearCachedRedraw

      public static void clearCachedRedraw()
    • redrawCachedIfAny

      public static void redrawCachedIfAny(org.joml.Matrix4f projection)
      Re-emit the last tick's MDI batch (atlas instance VBO already uploaded). Keeps static parts visible every render frame between game-tick uploads (~20 Hz).
    • submit

      public boolean submit(InstancedStaticPartRenderer renderer, int indexCount, int instanceCount, int instanceDataSize, FloatBuffer instanceDataFlipped, int[] sourceCullIndices, long[] sourceOcclusionKeys, ByteBuffer atlasVertexBytes, IntBuffer atlasIndices, int atlasIndexCount)