6666
6767import java .nio .DoubleBuffer ;
6868import java .util .ArrayList ;
69+ import java .util .Collections ;
70+ import java .util .EnumMap ;
6971import java .util .List ;
7072import java .util .Map ;
7173
@@ -92,6 +94,12 @@ public final class ShaderEngine {
9294
9395 /// runtime varying state
9496
97+ // TODO: [CUSTOM_TEX] Do we want to keep it loose like this?
98+ private static Map <CompositeTextureData , Texture2D > gbuffersCustomTex = Collections .emptyMap ();
99+ private static Map <CompositeTextureData , Texture2D > compositeCustomTex = Collections .emptyMap ();
100+ private static Map <CompositeTextureData , Texture2D > deferredCustomTex = Collections .emptyMap ();
101+
102+ // TODO: [CUSTOM_TEX] Do we bundle this with the custom textures?
95103 private static Texture2D noiseTex ;
96104
97105 private static DrawBuffers buffers ;
@@ -475,19 +483,82 @@ private static void init(Report report) {
475483
476484 ShadersCompositeMesh .init ();
477485
486+ gbuffersCustomTex = new EnumMap <>(CompositeTextureData .class );
487+ compositeCustomTex = new EnumMap <>(CompositeTextureData .class );
488+ deferredCustomTex = new EnumMap <>(CompositeTextureData .class );
489+
490+ if (!state .textures .isEmpty ()) {
491+ for (val stagedTex : state .textures ) {
492+ val index = BufferNameUtil .gbufferIndexFromName (stagedTex .bufferName ());
493+ if (index == null ) {
494+ Share .log .error ("Unknown buffer index for custom texture: {}" , stagedTex );
495+ continue ;
496+ }
497+
498+ val stagedCustomTexMap = switch (stagedTex .stage ()) {
499+ case "gbuffers" -> gbuffersCustomTex ;
500+ case "composite" -> compositeCustomTex ;
501+ case "deferred" -> deferredCustomTex ;
502+ default -> null ;
503+ };
504+ if (stagedCustomTexMap == null ) {
505+ Share .log .error ("Unknown stage for custom texture: {}" , stagedTex );
506+ continue ;
507+ }
508+
509+ if (stagedCustomTexMap .containsKey (index )) {
510+ Share .log .error ("Duplicate custom texture {} ignored" , stagedTex );
511+ continue ;
512+ }
513+
514+ val path = "/shaders/" + stagedTex .path ();
515+ val customTex = CustomTexture2D .load (state .pack , path );
516+ if (customTex == null ) {
517+ Share .log .error ("Missing custom texture {}, on exact path: {}" , stagedTex , path );
518+ continue ;
519+ }
520+
521+ stagedCustomTexMap .put (index , customTex );
522+ Share .log .debug ("Loaded Custom Texture: {}" , stagedTex );
523+ // TODO: Make format look like: deferred.colortex3<TAB>lib/textures/cloud-water.png<TAB>RGBA<TAB>256x256
524+ report .customTextures .put (stagedTex .path (),
525+ new Report .TextureInfo (customTex .width (),
526+ customTex .height (),
527+ BufferNameUtil .gbufferFormatNameFromEnum (customTex .internalFormat ())));
528+ }
529+ }
530+
531+ if (gbuffersCustomTex .isEmpty ()) {
532+ gbuffersCustomTex = Collections .emptyMap ();
533+ } else {
534+ gbuffersCustomTex = Collections .unmodifiableMap (gbuffersCustomTex );
535+ }
536+ if (compositeCustomTex .isEmpty ()) {
537+ compositeCustomTex = Collections .emptyMap ();
538+ } else {
539+ compositeCustomTex = Collections .unmodifiableMap (compositeCustomTex );
540+ }
541+ if (deferredCustomTex .isEmpty ()) {
542+ deferredCustomTex = Collections .emptyMap ();
543+ } else {
544+ deferredCustomTex = Collections .unmodifiableMap (deferredCustomTex );
545+ }
546+
478547 if (state .noiseTexPath != null ) {
479548 val path = "/shaders/" + state .noiseTexPath ;
480549 noiseTex = CustomTexture2D .load (state .pack , path );
481550 if (noiseTex == null ) {
482551 Share .log .error ("Missing noise texture: {}" , path );
483552 } else {
553+ // TODO: Make format look like: noise<TAB>lib/textures/noise.png<TAB>RGBA<TAB>128x128
484554 report .customTextures .put (state .noiseTexPath ,
485555 new Report .TextureInfo (noiseTex .width (),
486556 noiseTex .height (),
487557 BufferNameUtil .gbufferFormatNameFromEnum (noiseTex .internalFormat ())));
488558 }
489559 } else if (state .noiseTexSize != null ) {
490560 noiseTex = HFNoiseTexture2D .create (state .noiseTexSize , state .noiseTexSize );
561+ // TODO: Make format look like: noise<TAB>(builtin)<TAB>RGBA<TAB>128x128
491562 report .customTextures .put ("noise" ,
492563 new Report .TextureInfo (noiseTex .width (),
493564 noiseTex .height (),
@@ -516,6 +587,19 @@ private static void deinit() {
516587 }
517588
518589 shaderData .reset ();
590+ for (val tex : gbuffersCustomTex .values ()) {
591+ tex .deinit ();
592+ }
593+ gbuffersCustomTex = Collections .emptyMap ();
594+ for (val tex : compositeCustomTex .values ()) {
595+ tex .deinit ();
596+ }
597+ compositeCustomTex = Collections .emptyMap ();
598+ for (val tex : deferredCustomTex .values ()) {
599+ tex .deinit ();
600+ }
601+ deferredCustomTex = Collections .emptyMap ();
602+
519603 if (noiseTex != null ) {
520604 noiseTex .deinit ();
521605 noiseTex = null ;
@@ -932,6 +1016,7 @@ private static void renderShadowMap() {
9321016 }
9331017 }
9341018
1019+ // TODO: [CUSTOM_TEX] Bind the custom textures if applicable
9351020 public static void bindCompositeTextures (Map <CompositeTextureData , Texture2D > textures ) {
9361021 for (val entry : textures .entrySet ()) {
9371022 GL13 .glActiveTexture (GL13 .GL_TEXTURE0 + entry .getKey ().gpuIndex ());
0 commit comments