11package net .conczin .immersive_paintings ;
22
3+ import com .mojang .blaze3d .platform .NativeImage ;
4+ import net .conczin .immersive_paintings .Painting .Size ;
35import net .conczin .immersive_paintings .client .gui .ImmersivePaintingScreen ;
46import net .conczin .immersive_paintings .network .NetworkHandler ;
57import net .conczin .immersive_paintings .network .payload .c2s .ImageRequestPayload ;
6- import net .conczin .immersive_paintings .Painting .Size ;
78import net .conczin .immersive_paintings .registration .Configs ;
89import net .conczin .immersive_paintings .util .Cache ;
910import net .conczin .immersive_paintings .util .ImageManipulations ;
1011import net .minecraft .client .Minecraft ;
1112import net .minecraft .client .renderer .texture .DynamicTexture ;
1213import net .minecraft .client .renderer .texture .TextureManager ;
13- import net .minecraft .resources .ResourceLocation ;
14+ import net .minecraft .resources .Identifier ;
1415
1516import java .awt .image .BufferedImage ;
1617import java .io .IOException ;
1718import java .util .Collections ;
1819import java .util .HashMap ;
1920import java .util .Map ;
2021import java .util .Optional ;
21- import java .util .concurrent .*;
22+ import java .util .concurrent .ExecutorService ;
23+ import java .util .concurrent .Executors ;
2224
2325public class ClientPaintingManager {
24- private static final Map <ResourceLocation , Painting > paintings = Collections .synchronizedMap (new HashMap <>());
26+ private static final Map <Identifier , Painting > paintings = Collections .synchronizedMap (new HashMap <>());
2527
26- private static final Map <ResourceLocation , Map <Size , ResourceLocation >> textureMap = Collections .synchronizedMap (new HashMap <>());
28+ private static final Map <Identifier , Map <Size , Identifier >> textureMap = Collections .synchronizedMap (new HashMap <>());
2729
2830 private static final Map <String , Boolean > requested = Collections .synchronizedMap (new HashMap <>());
2931
3032 private static final ClientCache paintingCache = new ClientCache ();
3133
3234 private final static ExecutorService service = Executors .newFixedThreadPool (2 );
3335
34- public static Map <ResourceLocation , Painting > getPaintings () {
36+ public static Map <Identifier , Painting > getPaintings () {
3537 return paintings ;
3638 }
3739
38- public static Optional <Painting > getPainting (ResourceLocation identifier ) {
40+ public static Optional <Painting > getPainting (Identifier identifier ) {
3941 return Optional .ofNullable (paintings .get (identifier ));
4042 }
4143
42- private static String textureIdentifier (ResourceLocation identifier , Size size ) {
44+ private static String textureIdentifier (Identifier identifier , Size size ) {
4345 if (size == Size .FULL )
4446 return identifier .getPath ();
4547 return identifier .getPath () + "_" + size .name ().toLowerCase ();
4648 }
4749
48- private static void setImageRequest (ResourceLocation identifier , boolean thumbnail , boolean delete ) {
50+ private static void setImageRequest (Identifier identifier , boolean thumbnail , boolean delete ) {
4951 String id = textureIdentifier (identifier , thumbnail ? Size .THUMBNAIL : Size .FULL );
5052 if (requested .containsKey (id ) == delete ) {
5153 if (delete ) {
@@ -57,7 +59,7 @@ private static void setImageRequest(ResourceLocation identifier, boolean thumbna
5759 }
5860 }
5961
60- private static ResourceLocation getOrNSFW (Map <Size , ResourceLocation > mapping , ResourceLocation identifier , Size size ) {
62+ private static Identifier getOrNSFW (Map <Size , Identifier > mapping , Identifier identifier , Size size ) {
6163 if (Configs .CLIENT .showNSFWPaintings )
6264 return mapping .get (size );
6365
@@ -79,11 +81,11 @@ private static ResourceLocation getOrNSFW(Map<Size, ResourceLocation> mapping, R
7981 return Painting .DEFAULT_IDENTIFIER ;
8082 }
8183
82- public static ResourceLocation getImageIdentifier (ResourceLocation identifier , Size size ) {
84+ public static Identifier getImageIdentifier (Identifier identifier , Size size ) {
8385 if (!paintings .containsKey (identifier ))
8486 return Painting .DEFAULT_IDENTIFIER ;
8587
86- Map <Size , ResourceLocation > mapping = textureMap .get (identifier );
88+ Map <Size , Identifier > mapping = textureMap .get (identifier );
8789
8890 if (mapping == null ) {
8991 // Attempt to get the thumbnail first so there's at least something displayed
@@ -109,7 +111,7 @@ public static ResourceLocation getImageIdentifier(ResourceLocation identifier, S
109111 return getOrNSFW (mapping , identifier , size );
110112 }
111113
112- public static void registerPainting (ResourceLocation identifier , Painting painting ) {
114+ public static void registerPainting (Identifier identifier , Painting painting ) {
113115 String fullId = textureIdentifier (identifier , Size .FULL );
114116 String thumbId = textureIdentifier (identifier , Size .THUMBNAIL );
115117
@@ -134,13 +136,13 @@ public static void registerPainting(ResourceLocation identifier, Painting painti
134136 );
135137 }
136138
137- public static void deregisterPainting (ResourceLocation identifier ) {
139+ public static void deregisterPainting (Identifier identifier ) {
138140 if (!paintings .containsKey (identifier ))
139141 return ;
140142
141143 paintings .remove (identifier );
142144
143- Map <Size , ResourceLocation > map = textureMap .remove (identifier );
145+ Map <Size , Identifier > map = textureMap .remove (identifier );
144146 if (map != null ) {
145147 TextureManager manager = Minecraft .getInstance ().getTextureManager ();
146148 map .forEach ((size , id ) -> {
@@ -150,9 +152,9 @@ public static void deregisterPainting(ResourceLocation identifier) {
150152 }
151153 }
152154
153- private static void registerImageType (ResourceLocation identifier , BufferedImage fullImage , Size size , Size realSize , final boolean alreadyCached ) {
155+ private static void registerImageType (Identifier identifier , BufferedImage fullImage , Size size , Size realSize , final boolean alreadyCached ) {
154156 textureMap .putIfAbsent (identifier , new HashMap <>());
155- Map <Size , ResourceLocation > mapping = textureMap .get (identifier );
157+ Map <Size , Identifier > mapping = textureMap .get (identifier );
156158
157159 // Handle cases where an image is too small, and realSize == Size.HALF/QUARTER/EIGHTH but size == Size.FULL
158160 if (mapping .containsKey (size ) && size != realSize ) {
@@ -178,22 +180,29 @@ private static void registerImageType(ResourceLocation identifier, BufferedImage
178180 paintingCache .set (path , target );
179181 }
180182
181- ResourceLocation id = Minecraft . getInstance (). getTextureManager (). register ( Main .MOD_ID + "/" + path , new DynamicTexture ( ImageManipulations . bufferedToNative ( target )) );
182- mapping . put ( realSize , id );
183+ Identifier id = Main .locate ( path );
184+ NativeImage nativeImage = ImageManipulations . bufferedToNative ( target );
183185
184- if (size == Size .THUMBNAIL && Minecraft .getInstance ().screen instanceof ImmersivePaintingScreen screen )
185- screen .updateWidget (identifier );
186+ // DynamicTexture construction calls RenderSystem GPU methods (createTexture, upload)
187+ // which must run on the render/main thread. Schedule it there.
188+ Minecraft .getInstance ().execute (() -> {
189+ Minecraft .getInstance ().getTextureManager ().register (id , new DynamicTexture (() -> "immersive_paintings_" + path , nativeImage ));
190+ mapping .put (realSize , id );
191+
192+ if (size == Size .THUMBNAIL && Minecraft .getInstance ().screen instanceof ImmersivePaintingScreen screen )
193+ screen .updateWidget (identifier );
194+ });
186195 });
187196 }
188197
189- public static void registerThumbnail (ResourceLocation identifier , BufferedImage image , boolean alreadyCached ) {
198+ public static void registerThumbnail (Identifier identifier , BufferedImage image , boolean alreadyCached ) {
190199 registerImageType (identifier , image , Size .THUMBNAIL , Size .THUMBNAIL , alreadyCached );
191200 setImageRequest (identifier , true , true );
192201 }
193202
194203 // TODO: for datapacks, use FULL for all sizes that aren't thumbnail
195204 // registers this textures and make it readable
196- public static void registerImage (ResourceLocation identifier , BufferedImage image , boolean alreadyCached ) {
205+ public static void registerImage (Identifier identifier , BufferedImage image , boolean alreadyCached ) {
197206 if (!paintings .containsKey (identifier ) && !alreadyCached ) {
198207 Main .LOGGER .error ("no existing painting record for identifier {}" , identifier );
199208 return ;
0 commit comments