diff --git a/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs b/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs index d81360f..9cf6dc5 100644 --- a/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs +++ b/src/AcDream.App/Rendering/Wb/WbDrawDispatcher.cs @@ -398,21 +398,10 @@ public sealed unsafe class WbDrawDispatcher : IDisposable private void DrawGroup(InstanceGroup grp) { - _gl.ActiveTexture(TextureUnit.Texture0); - _gl.BindTexture(TextureTarget.Texture2D, grp.TextureHandle); - _gl.BindBuffer(BufferTargetARB.ElementArrayBuffer, grp.Ibo); - - // BaseInstance offsets the per-instance attribute fetches into our - // shared instance VBO so each group reads its own slice. Requires - // GL_ARB_base_instance (GL 4.2+); WB requires 4.3 so this is available. - _gl.DrawElementsInstancedBaseVertexBaseInstance( - PrimitiveType.Triangles, - (uint)grp.IndexCount, - DrawElementsType.UnsignedShort, - (void*)(grp.FirstIndex * sizeof(ushort)), - (uint)grp.InstanceCount, - grp.BaseVertex, - (uint)grp.FirstInstance); + throw new NotImplementedException( + "DrawGroup is being removed in Task 10 — the dispatcher rewrites Draw() " + + "to use glMultiDrawElementsIndirect instead of per-group draws. " + + "If this throws at runtime, Task 10 hasn't landed yet."); } private void MaybeFlushDiag() @@ -452,12 +441,16 @@ public sealed unsafe class WbDrawDispatcher : IDisposable : TranslucencyKind.Opaque; } - uint texHandle = ResolveTexture(entity, meshRef, batch, palHash); + ulong texHandle = ResolveTexture(entity, meshRef, batch, palHash); if (texHandle == 0) continue; + // TextureLayer is always 0 for per-instance composites; non-zero when + // WB atlas is adopted in N.6+ and batches reference a shared atlas layer. + uint texLayer = 0; + var key = new GroupKey( batch.IBO, batch.FirstIndex, (int)batch.BaseVertex, - batch.IndexCount, texHandle, translucency); + batch.IndexCount, texHandle, texLayer, translucency); if (!_groups.TryGetValue(key, out var grp)) { @@ -467,7 +460,8 @@ public sealed unsafe class WbDrawDispatcher : IDisposable FirstIndex = batch.FirstIndex, BaseVertex = (int)batch.BaseVertex, IndexCount = batch.IndexCount, - TextureHandle = texHandle, + BindlessTextureHandle = texHandle, + TextureLayer = texLayer, Translucency = translucency, }; _groups[key] = grp; @@ -476,10 +470,8 @@ public sealed unsafe class WbDrawDispatcher : IDisposable } } - private uint ResolveTexture(WorldEntity entity, MeshRef meshRef, ObjectRenderBatch batch, ulong palHash) + private ulong ResolveTexture(WorldEntity entity, MeshRef meshRef, ObjectRenderBatch batch, ulong palHash) { - // WB stores the surface id on batch.Key.SurfaceId (TextureKey struct); - // batch.SurfaceId is unset (zero) for batches built by ObjectMeshManager. uint surfaceId = batch.Key.SurfaceId; if (surfaceId == 0 || surfaceId == 0xFFFFFFFF) return 0; @@ -490,19 +482,16 @@ public sealed unsafe class WbDrawDispatcher : IDisposable if (entity.PaletteOverride is not null) { - // perf #4: pass the entity-precomputed palette hash so TextureCache - // can skip its internal HashPaletteOverride for repeat lookups - // within the same character. - return _textures.GetOrUploadWithPaletteOverride( + return _textures.GetOrUploadWithPaletteOverrideBindless( surfaceId, origTexOverride, entity.PaletteOverride, palHash); } else if (hasOrigTexOverride) { - return _textures.GetOrUploadWithOrigTextureOverride(surfaceId, overrideOrigTex); + return _textures.GetOrUploadWithOrigTextureOverrideBindless(surfaceId, overrideOrigTex); } else { - return _textures.GetOrUpload(surfaceId); + return _textures.GetOrUploadBindless(surfaceId); } } @@ -545,7 +534,8 @@ public sealed unsafe class WbDrawDispatcher : IDisposable uint FirstIndex, int BaseVertex, int IndexCount, - uint TextureHandle, + ulong BindlessTextureHandle, + uint TextureLayer, TranslucencyKind Translucency); private sealed class InstanceGroup @@ -554,7 +544,8 @@ public sealed unsafe class WbDrawDispatcher : IDisposable public uint FirstIndex; public int BaseVertex; public int IndexCount; - public uint TextureHandle; + public ulong BindlessTextureHandle; // 64-bit (was uint TextureHandle in N.4) + public uint TextureLayer; // 0 for per-instance composites; non-zero when WB atlas is adopted in N.6+ public TranslucencyKind Translucency; public int FirstInstance; // offset into the shared instance VBO (in instances, not bytes) public int InstanceCount;