mirror of https://github.com/kami-blue/client
parent
9c0c237650
commit
3f2e0c486d
|
@ -12,10 +12,11 @@ import kotlinx.coroutines.launch
|
||||||
import me.zeroeightsix.kami.KamiMod
|
import me.zeroeightsix.kami.KamiMod
|
||||||
import me.zeroeightsix.kami.manager.Manager
|
import me.zeroeightsix.kami.manager.Manager
|
||||||
import me.zeroeightsix.kami.util.Wrapper
|
import me.zeroeightsix.kami.util.Wrapper
|
||||||
|
import me.zeroeightsix.kami.util.graphics.TextureUtils
|
||||||
import me.zeroeightsix.kami.util.threads.mainScope
|
import me.zeroeightsix.kami.util.threads.mainScope
|
||||||
import me.zeroeightsix.kami.util.threads.onMainThreadW
|
import me.zeroeightsix.kami.util.threads.onMainThreadW
|
||||||
import net.minecraft.client.renderer.texture.DynamicTexture
|
|
||||||
import net.minecraft.util.ResourceLocation
|
import net.minecraft.util.ResourceLocation
|
||||||
|
import org.lwjgl.opengl.GL11.GL_RGBA
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.FileInputStream
|
import java.io.FileInputStream
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
@ -125,7 +126,7 @@ object KamiMojiManager : Manager {
|
||||||
val image = ImageIO.read(file)
|
val image = ImageIO.read(file)
|
||||||
|
|
||||||
onMainThreadW(5000L) {
|
onMainThreadW(5000L) {
|
||||||
val dynamicTexture = DynamicTexture(image)
|
val dynamicTexture = TextureUtils.genTextureWithMipmaps(image, 3, GL_RGBA)
|
||||||
val resourceLocation = Wrapper.minecraft.textureManager.getDynamicTextureLocation(name, dynamicTexture)
|
val resourceLocation = Wrapper.minecraft.textureManager.getDynamicTextureLocation(name, dynamicTexture)
|
||||||
emojiMap[name] = resourceLocation
|
emojiMap[name] = resourceLocation
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,12 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
|
||||||
public abstract class MixinFontRenderer {
|
public abstract class MixinFontRenderer {
|
||||||
|
|
||||||
@Shadow public int FONT_HEIGHT;
|
@Shadow public int FONT_HEIGHT;
|
||||||
@Shadow public float alpha;
|
@Shadow private float alpha;
|
||||||
@Shadow public float posX;
|
@Shadow protected float posX;
|
||||||
@Shadow public float posY;
|
@Shadow protected float posY;
|
||||||
@Shadow public float red;
|
@Shadow private float red;
|
||||||
@Shadow public float green;
|
@Shadow private float green;
|
||||||
@Shadow public float blue;
|
@Shadow private float blue;
|
||||||
|
|
||||||
@Shadow
|
@Shadow
|
||||||
protected abstract void renderStringAtPos(String text, boolean shadow);
|
protected abstract void renderStringAtPos(String text, boolean shadow);
|
||||||
|
@ -38,7 +38,7 @@ public abstract class MixinFontRenderer {
|
||||||
@Redirect(method = "renderString", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/FontRenderer;renderStringAtPos(Ljava/lang/String;Z)V"))
|
@Redirect(method = "renderString", at = @At(value = "INVOKE", target = "Lnet/minecraft/client/gui/FontRenderer;renderStringAtPos(Ljava/lang/String;Z)V"))
|
||||||
private void renderStringAtPos(FontRenderer fontRenderer, String text, boolean shadow) {
|
private void renderStringAtPos(FontRenderer fontRenderer, String text, boolean shadow) {
|
||||||
if (KamiMoji.INSTANCE.isEnabled() && text.contains(":")) {
|
if (KamiMoji.INSTANCE.isEnabled() && text.contains(":")) {
|
||||||
text = KamiMoji.getText(text, FONT_HEIGHT, shadow, posX, posY, alpha);
|
text = KamiMoji.renderText(text, FONT_HEIGHT, shadow, posX, posY, alpha);
|
||||||
}
|
}
|
||||||
|
|
||||||
GlStateManager.color(red, blue, green, alpha); // Big Mojang meme :monkey:
|
GlStateManager.color(red, blue, green, alpha); // Big Mojang meme :monkey:
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
package me.zeroeightsix.kami.module.modules.chat
|
package me.zeroeightsix.kami.module.modules.chat
|
||||||
|
|
||||||
import me.zeroeightsix.kami.manager.managers.KamiMojiManager.getEmoji
|
import me.zeroeightsix.kami.manager.managers.KamiMojiManager
|
||||||
import me.zeroeightsix.kami.manager.managers.KamiMojiManager.isEmoji
|
|
||||||
import me.zeroeightsix.kami.module.Module
|
import me.zeroeightsix.kami.module.Module
|
||||||
import me.zeroeightsix.kami.util.graphics.GlStateUtils.resetTexParam
|
import me.zeroeightsix.kami.util.graphics.GlStateUtils.resetTexParam
|
||||||
import net.minecraft.client.renderer.GlStateManager
|
import net.minecraft.client.renderer.GlStateManager
|
||||||
|
@ -9,7 +8,9 @@ import net.minecraft.client.renderer.Tessellator
|
||||||
import net.minecraft.client.renderer.vertex.DefaultVertexFormats
|
import net.minecraft.client.renderer.vertex.DefaultVertexFormats
|
||||||
import net.minecraft.util.ResourceLocation
|
import net.minecraft.util.ResourceLocation
|
||||||
import org.kamiblue.commons.extension.ceilToInt
|
import org.kamiblue.commons.extension.ceilToInt
|
||||||
import org.lwjgl.opengl.GL11
|
import org.lwjgl.opengl.GL11.*
|
||||||
|
import org.lwjgl.opengl.GL12.GL_CLAMP_TO_EDGE
|
||||||
|
import org.lwjgl.opengl.GL14.GL_TEXTURE_LOD_BIAS
|
||||||
|
|
||||||
object KamiMoji : Module(
|
object KamiMoji : Module(
|
||||||
name = "KamiMoji",
|
name = "KamiMoji",
|
||||||
|
@ -17,18 +18,18 @@ object KamiMoji : Module(
|
||||||
category = Category.CHAT
|
category = Category.CHAT
|
||||||
) {
|
) {
|
||||||
@JvmStatic
|
@JvmStatic
|
||||||
fun getText(inputText: String, fontHeight: Int, shadow: Boolean, posX: Float, posY: Float, alpha: Float): String {
|
fun renderText(inputText: String, fontHeight: Int, shadow: Boolean, posX: Float, posY: Float, alpha: Float): String {
|
||||||
var text = inputText
|
var text = inputText
|
||||||
|
|
||||||
for (possible in text.split(":").toTypedArray()) {
|
for (possible in text.split(":").toTypedArray()) {
|
||||||
if (isEmoji(possible)) {
|
if (KamiMojiManager.isEmoji(possible)) {
|
||||||
val emojiText = ":$possible:"
|
val emojiText = ":$possible:"
|
||||||
if (!shadow) {
|
if (!shadow) {
|
||||||
val index = text.indexOf(emojiText)
|
val index = text.indexOf(emojiText)
|
||||||
if (index == -1) continue
|
if (index == -1) continue
|
||||||
|
|
||||||
val x = mc.fontRenderer.getStringWidth(text.substring(0, index)) + fontHeight / 4
|
val x = mc.fontRenderer.getStringWidth(text.substring(0, index)) + fontHeight / 4
|
||||||
drawEmoji(getEmoji(possible), (posX + x).toDouble(), posY.toDouble(), fontHeight.toFloat(), alpha)
|
drawEmoji(KamiMojiManager.getEmoji(possible), (posX + x).toDouble(), posY.toDouble(), fontHeight.toFloat(), alpha)
|
||||||
}
|
}
|
||||||
|
|
||||||
text = text.replaceFirst(emojiText, getReplacement(fontHeight))
|
text = text.replaceFirst(emojiText, getReplacement(fontHeight))
|
||||||
|
@ -44,7 +45,7 @@ object KamiMoji : Module(
|
||||||
var reducedWidth = inputWidth
|
var reducedWidth = inputWidth
|
||||||
|
|
||||||
for (possible in text.split(":")) {
|
for (possible in text.split(":")) {
|
||||||
if (isEmoji(possible)) {
|
if (KamiMojiManager.isEmoji(possible)) {
|
||||||
val emojiText = ":$possible:"
|
val emojiText = ":$possible:"
|
||||||
val emojiTextWidth = emojiText.sumBy { mc.fontRenderer.getCharWidth(it) }
|
val emojiTextWidth = emojiText.sumBy { mc.fontRenderer.getCharWidth(it) }
|
||||||
reducedWidth -= emojiTextWidth
|
reducedWidth -= emojiTextWidth
|
||||||
|
@ -68,8 +69,15 @@ object KamiMoji : Module(
|
||||||
val bufBuilder = tessellator.buffer
|
val bufBuilder = tessellator.buffer
|
||||||
|
|
||||||
mc.textureManager.bindTexture(emojiTexture)
|
mc.textureManager.bindTexture(emojiTexture)
|
||||||
GlStateManager.color(1f, 1f, 1f, alpha)
|
|
||||||
GlStateManager.glTexParameteri(GL11.GL_TEXTURE_2D, GL11.GL_TEXTURE_MIN_FILTER, GL11.GL_LINEAR)
|
GlStateManager.color(1.0f, 1.0f, 1.0f, alpha)
|
||||||
|
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE)
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR)
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR)
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, 0.0f)
|
||||||
|
|
||||||
bufBuilder.begin(7, DefaultVertexFormats.POSITION_TEX)
|
bufBuilder.begin(7, DefaultVertexFormats.POSITION_TEX)
|
||||||
bufBuilder.pos(x, y + size, 0.0).tex(0.0, 1.0).endVertex()
|
bufBuilder.pos(x, y + size, 0.0).tex(0.0, 1.0).endVertex()
|
||||||
|
@ -79,5 +87,6 @@ object KamiMoji : Module(
|
||||||
tessellator.draw()
|
tessellator.draw()
|
||||||
|
|
||||||
resetTexParam()
|
resetTexParam()
|
||||||
|
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,55 @@
|
||||||
|
package me.zeroeightsix.kami.util.graphics
|
||||||
|
|
||||||
|
import net.minecraft.client.renderer.GlStateManager
|
||||||
|
import net.minecraft.client.renderer.texture.DynamicTexture
|
||||||
|
import net.minecraft.client.renderer.texture.TextureUtil
|
||||||
|
import org.lwjgl.opengl.GL11.*
|
||||||
|
import org.lwjgl.opengl.GL12.*
|
||||||
|
import org.lwjgl.opengl.GL14.*
|
||||||
|
import java.awt.image.BufferedImage
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
|
||||||
|
object TextureUtils {
|
||||||
|
fun genTextureWithMipmaps(bufferedImage: BufferedImage, level: Int, textureFormat: Int) : DynamicTexture {
|
||||||
|
val dynamicTexture = DynamicTexture(bufferedImage)
|
||||||
|
val textureId = dynamicTexture.glTextureId
|
||||||
|
|
||||||
|
val depth = glGetBoolean(GL_DEPTH_TEST)
|
||||||
|
val blend = glGetBoolean(GL_BLEND)
|
||||||
|
GlStateUtils.depth(false)
|
||||||
|
GlStateUtils.blend(true)
|
||||||
|
GlStateManager.tryBlendFuncSeparate(GL_ONE, GL_ZERO, GL_SRC_ALPHA, GL_ZERO)
|
||||||
|
|
||||||
|
// Tells Gl that our texture isn't a repeating texture (edges are not connecting to each others)
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
|
||||||
|
|
||||||
|
// Setup texture filters
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
|
||||||
|
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST)
|
||||||
|
|
||||||
|
// Setup mipmap parameters
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0)
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, level)
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0)
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, level)
|
||||||
|
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, 0.0f)
|
||||||
|
GlStateManager.bindTexture(textureId)
|
||||||
|
|
||||||
|
for (mipmapLevel in 0..level) {
|
||||||
|
// GL_ALPHA means that the texture is a grayscale texture (black & white and alpha only)
|
||||||
|
glTexImage2D(GL_TEXTURE_2D, mipmapLevel, textureFormat, bufferedImage.width shr mipmapLevel, bufferedImage.height shr mipmapLevel, 0, textureFormat, GL_UNSIGNED_BYTE, null as ByteBuffer?)
|
||||||
|
}
|
||||||
|
|
||||||
|
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, 1)
|
||||||
|
TextureUtil.uploadTextureImageSub(textureId, bufferedImage, 0, 0, true, true)
|
||||||
|
|
||||||
|
GlStateUtils.resetTexParam()
|
||||||
|
GlStateUtils.depth(depth)
|
||||||
|
GlStateUtils.blend(blend)
|
||||||
|
GlStateManager.tryBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
|
||||||
|
|
||||||
|
return dynamicTexture
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,21 +1,15 @@
|
||||||
package me.zeroeightsix.kami.util.graphics.font
|
package me.zeroeightsix.kami.util.graphics.font
|
||||||
|
|
||||||
import me.zeroeightsix.kami.KamiMod
|
import me.zeroeightsix.kami.KamiMod
|
||||||
import me.zeroeightsix.kami.util.Wrapper
|
import me.zeroeightsix.kami.util.graphics.TextureUtils
|
||||||
import me.zeroeightsix.kami.util.graphics.GlStateUtils
|
|
||||||
import net.minecraft.client.renderer.GlStateManager
|
|
||||||
import net.minecraft.client.renderer.texture.DynamicTexture
|
import net.minecraft.client.renderer.texture.DynamicTexture
|
||||||
import net.minecraft.client.renderer.texture.TextureUtil
|
|
||||||
import org.kamiblue.commons.utils.MathUtils
|
import org.kamiblue.commons.utils.MathUtils
|
||||||
import org.lwjgl.opengl.GL11.*
|
import org.lwjgl.opengl.GL11.GL_ALPHA
|
||||||
import org.lwjgl.opengl.GL12.*
|
|
||||||
import org.lwjgl.opengl.GL14.*
|
|
||||||
import java.awt.Color
|
import java.awt.Color
|
||||||
import java.awt.Font
|
import java.awt.Font
|
||||||
import java.awt.Graphics2D
|
import java.awt.Graphics2D
|
||||||
import java.awt.RenderingHints
|
import java.awt.RenderingHints
|
||||||
import java.awt.image.BufferedImage
|
import java.awt.image.BufferedImage
|
||||||
import java.nio.ByteBuffer
|
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
|
||||||
|
@ -178,40 +172,7 @@ class FontGlyphs(val style: Style, private val font: Font, private val fallbackF
|
||||||
|
|
||||||
private fun createTexture(bufferedImage: BufferedImage): DynamicTexture? {
|
private fun createTexture(bufferedImage: BufferedImage): DynamicTexture? {
|
||||||
return try {
|
return try {
|
||||||
val dynamicTexture = DynamicTexture(bufferedImage)
|
TextureUtils.genTextureWithMipmaps(bufferedImage, 4, GL_ALPHA)
|
||||||
dynamicTexture.loadTexture(Wrapper.minecraft.resourceManager)
|
|
||||||
val textureId = dynamicTexture.glTextureId
|
|
||||||
|
|
||||||
// Tells Gl that our texture isn't a repeating texture (edges are not connecting to each others)
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE)
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE)
|
|
||||||
|
|
||||||
// Setup texture filters
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST)
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR)
|
|
||||||
glHint(GL_GENERATE_MIPMAP_HINT, GL_NICEST)
|
|
||||||
|
|
||||||
// Setup mipmap parameters
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_LOD, 0)
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LOD, 4)
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0)
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 4)
|
|
||||||
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_LOD_BIAS, 0f)
|
|
||||||
GlStateManager.bindTexture(textureId)
|
|
||||||
|
|
||||||
// We only need 4 levels of mipmaps for 64 sized font
|
|
||||||
// 0: 64 x 64, 1: 32 x 32, 2: 16 x 16, 3: 8 x 8, 4: 4 x 4
|
|
||||||
for (mipmapLevel in 0..4) {
|
|
||||||
// GL_ALPHA means that the texture is a grayscale texture (black & white and alpha only)
|
|
||||||
glTexImage2D(GL_TEXTURE_2D, mipmapLevel, GL_ALPHA, bufferedImage.width shr mipmapLevel, bufferedImage.height shr mipmapLevel, 0, GL_ALPHA, GL_UNSIGNED_BYTE, null as ByteBuffer?)
|
|
||||||
}
|
|
||||||
|
|
||||||
glTexParameteri(GL_TEXTURE_2D, GL_GENERATE_MIPMAP, 1)
|
|
||||||
TextureUtil.uploadTextureImageSub(textureId, bufferedImage, 0, 0, true, true)
|
|
||||||
|
|
||||||
GlStateUtils.resetTexParam()
|
|
||||||
|
|
||||||
dynamicTexture
|
|
||||||
} catch (e: Exception) {
|
} catch (e: Exception) {
|
||||||
KamiMod.LOG.error("Failed to create font texture.")
|
KamiMod.LOG.error("Failed to create font texture.")
|
||||||
e.printStackTrace()
|
e.printStackTrace()
|
||||||
|
|
Loading…
Reference in New Issue