package cn.academy.core.client; import cn.academy.core.AcademyCraft; import cn.academy.core.Resources; import cn.lambdalib.annoreg.core.Registrant; import cn.lambdalib.annoreg.mc.RegPreInitCallback; import cn.lambdalib.cgui.gui.component.TextBox; import cn.lambdalib.util.client.font.Fonts; import cn.lambdalib.util.client.font.IFont; import cn.lambdalib.util.client.font.TrueTypeFont; import cn.lambdalib.util.generic.RegistryUtils; import com.google.common.base.Throwables; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.client.Minecraft; import net.minecraft.client.renderer.texture.AbstractTexture; import net.minecraft.client.renderer.texture.ITextureObject; import net.minecraft.client.renderer.texture.SimpleTexture; import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.resources.IResourceManager; import net.minecraft.util.ResourceLocation; import net.minecraftforge.client.model.AdvancedModelLoader; import net.minecraftforge.client.model.IModelCustom; import net.minecraftforge.common.config.Configuration; import org.lwjgl.BufferUtils; import org.lwjgl.opengl.GL30; import javax.imageio.ImageIO; import java.awt.*; import java.awt.image.BufferedImage; import java.io.IOException; import java.nio.IntBuffer; import java.util.HashMap; import java.util.Map; import static org.lwjgl.opengl.GL11.*; import static org.lwjgl.opengl.GL12.GL_BGRA; import static org.lwjgl.opengl.GL12.GL_UNSIGNED_INT_8_8_8_8_REV; /** * A delegation for client resources loading. Should not refer to explicitly. * @see cn.academy.core.Resources */ @Registrant @SideOnly(Side.CLIENT) public class ClientResources { private static boolean fontsInit = false; private static TrueTypeFont font, fontBold, fontItalic; private static Map<String, IModelCustom> cachedModels = new HashMap<>(); public static IFont font() { checkFontInit(); return font; } public static IFont fontBold() { checkFontInit(); return fontBold; } public static IFont fontItalic() { checkFontInit(); return fontItalic; } public static ResourceLocation preloadMipmapTexture(String loc) { TextureManager texManager = Minecraft.getMinecraft().getTextureManager(); ResourceLocation ret = Resources.getTexture(loc); ITextureObject loadedTexture = texManager.getTexture(ret); if (loadedTexture == null) { try { BufferedImage buffer = ImageIO.read(RegistryUtils.getResourceStream(ret)); // Note: Here we should actually implement ITextureObject, // but that causes problems when running with SMC because SMC adds an abstract method in the base // interface (getMultiTexID) and we have no way to implement it easily. // However it is automatically implemented in AbstractTexture. texManager.loadTexture(ret, new AbstractTexture() { final int textureID = glGenTextures(); { int width = buffer.getWidth(), height = buffer.getHeight(); int[] data = new int[width * height]; buffer.getRGB(0, 0, width, height, data, 0, width); IntBuffer buffer1 = BufferUtils.createIntBuffer(data.length); buffer1.put(data).flip(); glBindTexture(GL_TEXTURE_2D, textureID); glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, buffer1); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); GL30.glGenerateMipmap(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); } @Override public void loadTexture(IResourceManager man) throws IOException {} @Override public int getGlTextureId() { return textureID; } }); } catch (Exception ex) { Throwables.propagate(ex); } } return ret; } public static ResourceLocation preloadTexture(String loc) { ResourceLocation ret = Resources.getTexture(loc); TextureManager texManager = Minecraft.getMinecraft().getTextureManager(); ITextureObject loadedTexture = texManager.getTexture(ret); if (loadedTexture == null) { Minecraft.getMinecraft().getTextureManager().loadTexture(ret, new SimpleTexture(ret)); } return ret; } public static TextBox newTextBox() { TextBox ret = new TextBox(); ret.font = font(); return ret; } public static TextBox newTextBox(IFont.FontOption option) { TextBox ret = new TextBox(option); ret.font = font(); return ret; } public static IModelCustom getModel(String mdlName) { IModelCustom ret = cachedModels.get(mdlName); if(ret != null) return ret; ret = AdvancedModelLoader.loadModel(Resources.res("models/" + mdlName + ".obj")); cachedModels.put(mdlName, ret); return ret; } private static void checkFontInit() { if (!fontsInit) { fontsInit = true; // TODO: Add this to settings page? Configuration config = AcademyCraft.config; String userSpecified = config.getString("font", "gui", "Microsoft YaHei", "The font to be used. If not found in the system, default fonts will be used."); font = TrueTypeFont.withFallback2(Font.PLAIN, 24, new String[] { userSpecified, "微软雅黑", "Microsoft YaHei", "SimHei", "Adobe Heiti Std R" }); fontBold = new TrueTypeFont(font.font().deriveFont(Font.BOLD)); fontItalic = new TrueTypeFont(font.font().deriveFont(Font.ITALIC)); } } @RegPreInitCallback private static void __preInit() { checkFontInit(); // TODO: Disaster if any ui initializes before preInit... Fonts.register("AC_Normal", font()); Fonts.register("AC_Bold", fontBold()); Fonts.register("AC_Italic", fontItalic()); } }