From 37974d40b94f8c908b5f29d6ab232067d2d40b3a Mon Sep 17 00:00:00 2001 From: DBotThePony Date: Mon, 10 Jul 2023 21:48:59 +0700 Subject: [PATCH] Refine render methods and functions --- .../otm/android/AndroidSwitchableFeature.kt | 8 +- .../android/feature/EnderTeleporterFeature.kt | 5 +- .../otm/android/feature/ItemMagnetFeature.kt | 5 +- .../otm/android/feature/JumpBoostFeature.kt | 13 +- .../otm/android/feature/NightVisionFeature.kt | 7 +- .../otm/android/feature/ShockwaveFeature.kt | 13 +- .../otm/android/feature/StepAssistFeature.kt | 5 +- .../energy/IMatteryEnergyStorage.kt | 2 +- .../otm/capability/matter/IMatterStorage.kt | 2 +- .../otm/capability/matter/IPatternStorage.kt | 2 +- .../mc/otm/client/AndroidAbilityKeyMapping.kt | 13 +- .../dbotthepony/mc/otm/client/MatteryGUI.kt | 22 +- .../client/render/AbstractMatterySprite.kt | 272 ++-------- .../dbotthepony/mc/otm/client/render/Ext.kt | 43 +- .../mc/otm/client/render/IGUIRenderable.kt | 38 +- .../mc/otm/client/render/MatterySprite.kt | 12 +- .../mc/otm/client/render/RenderHelper.kt | 478 +++++------------- .../mc/otm/client/render/UVStuff.kt | 168 +++--- .../client/render/blockentity/BankRenderer.kt | 11 +- .../render/blockentity/BlackHoleRenderer.kt | 3 +- .../render/blockentity/HoloSignRenderer.kt | 2 +- .../mc/otm/client/screen/panels/FramePanel.kt | 6 +- .../mc/otm/client/screen/panels/Label.kt | 36 +- .../screen/panels/button/ButtonPanel.kt | 2 +- .../screen/panels/input/TextInputPanel.kt | 4 +- .../screen/panels/slot/AbstractSlotPanel.kt | 3 +- .../client/screen/panels/slot/SlotPanel.kt | 6 +- .../panels/slot/UserFilteredSlotPanel.kt | 11 +- .../screen/tech/AndroidStationScreen.kt | 45 +- .../dbotthepony/mc/otm/core/math/RGBAColor.kt | 66 +-- .../mc/otm/item/weapon/AbstractWeaponItem.kt | 14 +- 31 files changed, 424 insertions(+), 893 deletions(-) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidSwitchableFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidSwitchableFeature.kt index bc52c0b0e..a17deba7c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidSwitchableFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/AndroidSwitchableFeature.kt @@ -1,9 +1,9 @@ package ru.dbotthepony.mc.otm.android -import com.mojang.blaze3d.vertex.PoseStack import net.minecraft.client.gui.GuiGraphics import net.minecraft.nbt.CompoundTag import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability +import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.core.nbt.set abstract class AndroidSwitchableFeature(type: AndroidFeatureType<*>, android: MatteryPlayerCapability) : AndroidFeature(type, android) { @@ -25,7 +25,7 @@ abstract class AndroidSwitchableFeature(type: AndroidFeatureType<*>, android: Ma open val allowToSwitchByPlayerWhileSpectator: Boolean get() = true open val maxCooldown: Int get() = 0 - open var cooldown by synchronizer.int() + open var cooldown by synchronizer.int().property val isOnCooldown: Boolean get() = maxCooldown > 0 && cooldown > 0 @@ -38,9 +38,9 @@ abstract class AndroidSwitchableFeature(type: AndroidFeatureType<*>, android: Ma cooldown = maxCooldown } - // TODO: PoseStack is stripped from server dist + // TODO: GuiGraphics is stripped from server dist // but it doesn't seem to cause issues? - abstract fun renderIcon(graphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float) + abstract fun renderIcon(graphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, color: RGBAColor = RGBAColor.WHITE) override fun serializeNBT(): CompoundTag { return super.serializeNBT().also { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/EnderTeleporterFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/EnderTeleporterFeature.kt index 5e5931bbb..e8a417e10 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/EnderTeleporterFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/EnderTeleporterFeature.kt @@ -38,6 +38,7 @@ import ru.dbotthepony.mc.otm.config.AndroidConfig import ru.dbotthepony.mc.otm.core.genericPositions import ru.dbotthepony.mc.otm.core.holder import ru.dbotthepony.mc.otm.core.isFall +import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.core.math.Vector import ru.dbotthepony.mc.otm.core.math.asVector import ru.dbotthepony.mc.otm.core.math.component1 @@ -372,12 +373,12 @@ class EnderTeleporterFeature(capability: MatteryPlayerCapability) : AndroidActiv } } - override fun renderIcon(graphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float) { + override fun renderIcon(graphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, color: RGBAColor) { if (cooldown > 0) { RenderSystem.setShaderColor(1f, 0.4f, 0.4f, 1f) } - ResearchIcons.ICON_ENDER_TELEPORT.render(graphics, x, y, width, height) + ResearchIcons.ICON_ENDER_TELEPORT.render(graphics, x, y, width, height, color = color) if (cooldown > 0) { RenderSystem.setShaderColor(1f, 1f, 1f, 1f) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ItemMagnetFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ItemMagnetFeature.kt index 46e9c4477..bafb85a0a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ItemMagnetFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ItemMagnetFeature.kt @@ -21,6 +21,7 @@ import ru.dbotthepony.mc.otm.client.render.ResearchIcons import ru.dbotthepony.mc.otm.core.math.Vector import ru.dbotthepony.mc.otm.core.util.formatPower import ru.dbotthepony.mc.otm.core.getEntitiesInEllipsoid +import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.core.math.minus import ru.dbotthepony.mc.otm.core.math.plus import ru.dbotthepony.mc.otm.core.position @@ -129,7 +130,7 @@ class ItemMagnetFeature(capability: MatteryPlayerCapability) : AndroidSwitchable } } - override fun renderIcon(graphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float) { - ResearchIcons.ICON_ITEM_MAGNET.render(graphics, x, y, width, height) + override fun renderIcon(graphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, color: RGBAColor) { + ResearchIcons.ICON_ITEM_MAGNET.render(graphics, x, y, width, height, color = color) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/JumpBoostFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/JumpBoostFeature.kt index 002bf99f2..fe281455d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/JumpBoostFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/JumpBoostFeature.kt @@ -26,6 +26,7 @@ import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.client.ShiftPressedCond import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.render.ResearchIcons +import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.core.math.Vector import ru.dbotthepony.mc.otm.core.math.component1 import ru.dbotthepony.mc.otm.core.math.component2 @@ -150,15 +151,7 @@ class JumpBoostFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF } } - override fun renderIcon(graphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float) { - if (cooldown > 0) { - RenderSystem.setShaderColor(1f, 0.4f, 0.4f, 1f) - } - - ResearchIcons.ICON_JUMP_BOOST.render(graphics, x, y, width, height) - - if (cooldown > 0) { - RenderSystem.setShaderColor(1f, 1f, 1f, 1f) - } + override fun renderIcon(graphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, color: RGBAColor) { + ResearchIcons.ICON_JUMP_BOOST.render(graphics, x, y, width, height, color = if (cooldown > 0) color * RGBAColor.REDDISH else color) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NightVisionFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NightVisionFeature.kt index 01f5dc6ea..c7241d161 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NightVisionFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/NightVisionFeature.kt @@ -1,15 +1,14 @@ package ru.dbotthepony.mc.otm.android.feature -import com.mojang.blaze3d.vertex.PoseStack import net.minecraft.client.gui.GuiGraphics import net.minecraft.world.effect.MobEffectInstance import net.minecraft.world.effect.MobEffects -import ru.dbotthepony.mc.otm.config.ServerConfig import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability import ru.dbotthepony.mc.otm.capability.energy.extractEnergyExact import ru.dbotthepony.mc.otm.client.render.ResearchIcons import ru.dbotthepony.mc.otm.config.AndroidConfig +import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.registry.AndroidFeatures class NightVisionFeature(android: MatteryPlayerCapability) : AndroidSwitchableFeature(AndroidFeatures.NIGHT_VISION, android) { @@ -34,7 +33,7 @@ class NightVisionFeature(android: MatteryPlayerCapability) : AndroidSwitchableFe } } - override fun renderIcon(graphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float) { - ResearchIcons.ICON_NIGHT_VISION.render(graphics, x, y, width, height) + override fun renderIcon(graphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, color: RGBAColor) { + ResearchIcons.ICON_NIGHT_VISION.render(graphics, x, y, width, height, color = color) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ShockwaveFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ShockwaveFeature.kt index ce0fbb20c..faad7ecd9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ShockwaveFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/ShockwaveFeature.kt @@ -34,6 +34,7 @@ import ru.dbotthepony.mc.otm.network.MatteryPlayerNetworkChannel import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.client.ShiftPressedCond import ru.dbotthepony.mc.otm.core.damageType +import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.network.MatteryPacket import ru.dbotthepony.mc.otm.network.ShockwaveEffectPacket import ru.dbotthepony.mc.otm.network.enqueueWork @@ -240,15 +241,7 @@ class ShockwaveFeature(capability: MatteryPlayerCapability) : AndroidSwitchableF ticker(false) } - override fun renderIcon(graphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float) { - if (isOnCooldown) { - RenderSystem.setShaderColor(1f, 0.4f, 0.4f, 1f) - } - - ResearchIcons.ICON_SHOCKWAVE.render(graphics, x, y, width, height) - - if (isOnCooldown) { - RenderSystem.setShaderColor(1f, 1f, 1f, 1f) - } + override fun renderIcon(graphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, color: RGBAColor) { + ResearchIcons.ICON_SHOCKWAVE.render(graphics, x, y, width, height, color = if (isOnCooldown) color * RGBAColor.REDDISH else color) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/StepAssistFeature.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/StepAssistFeature.kt index 81f3be363..a26e62bd8 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/StepAssistFeature.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/android/feature/StepAssistFeature.kt @@ -7,6 +7,7 @@ import net.minecraftforge.common.ForgeMod import ru.dbotthepony.mc.otm.android.AndroidSwitchableFeature import ru.dbotthepony.mc.otm.capability.MatteryPlayerCapability import ru.dbotthepony.mc.otm.client.render.ResearchIcons +import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.registry.AndroidFeatures import java.util.* @@ -54,8 +55,8 @@ class StepAssistFeature(android: MatteryPlayerCapability) : AndroidSwitchableFea sharedTick() } - override fun renderIcon(graphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float) { - ResearchIcons.ICON_STEP_ASSIST.render(graphics, x, y, width, height) + override fun renderIcon(graphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, color: RGBAColor) { + ResearchIcons.ICON_STEP_ASSIST.render(graphics, x, y, width, height, color = color) } companion object { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/IMatteryEnergyStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/IMatteryEnergyStorage.kt index 53407ac9d..98ad13ab6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/IMatteryEnergyStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/energy/IMatteryEnergyStorage.kt @@ -366,5 +366,5 @@ fun IMatteryEnergyStorage.getBarWidth(): Int { } fun IMatteryEnergyStorage.getBarColor(): Int { - return RGBAColor.LOW_POWER.linearInterpolation((batteryLevel / maxBatteryLevel).toFloat(), RGBAColor.FULL_POWER).toInt() + return RGBAColor.LOW_POWER.linearInterpolation((batteryLevel / maxBatteryLevel).toFloat(), RGBAColor.FULL_POWER).toRGB() } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IMatterStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IMatterStorage.kt index 7c75ad595..196389911 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IMatterStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IMatterStorage.kt @@ -123,7 +123,7 @@ fun IMatterStorage.getBarWidth(): Int { } fun IMatterStorage.getBarColor(): Int { - return RGBAColor.LOW_MATTER.linearInterpolation((storedMatter / maxStoredMatter).toFloat(), RGBAColor.FULL_MATTER).toInt() + return RGBAColor.LOW_MATTER.linearInterpolation((storedMatter / maxStoredMatter).toFloat(), RGBAColor.FULL_MATTER).toRGB() } val ICapabilityProvider.matter: IMatterStorage? get() = getCapability(MatteryCapability.MATTER).orNull() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IPatternStorage.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IPatternStorage.kt index 087d02a65..b43508eb6 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IPatternStorage.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/capability/matter/IPatternStorage.kt @@ -73,7 +73,7 @@ fun IPatternStorage.getBarWidth(): Int { } fun IPatternStorage.getBarColor(): Int { - return RGBAColor.LOW_PATTERNS.linearInterpolation((storedPatterns / patternCapacity).toFloat(), RGBAColor.FULL_PATTERNS).toInt() + return RGBAColor.LOW_PATTERNS.linearInterpolation((storedPatterns / patternCapacity).toFloat(), RGBAColor.FULL_PATTERNS).toRGB() } val ICapabilityProvider.patterns: IPatternStorage? get() = getCapability(MatteryCapability.PATTERN).orNull() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/AndroidAbilityKeyMapping.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/AndroidAbilityKeyMapping.kt index 41b816802..72ec6ec00 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/AndroidAbilityKeyMapping.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/AndroidAbilityKeyMapping.kt @@ -11,7 +11,7 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters import ru.dbotthepony.mc.otm.android.AndroidActiveFeature import ru.dbotthepony.mc.otm.capability.matteryPlayer import ru.dbotthepony.mc.otm.client.render.Widgets18 -import ru.dbotthepony.mc.otm.client.render.drawRect +import ru.dbotthepony.mc.otm.client.render.renderRect import ru.dbotthepony.mc.otm.client.render.is3DContext import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.network.ActivateAndroidFeaturePacket @@ -58,25 +58,16 @@ object AndroidAbilityKeyMapping : KeyMapping("key.otm.android_ability", KeyConfl val x = minecraft.window.guiScaledWidth.toFloat() * .5f + iconSize / 2f val y = minecraft.window.guiScaledHeight.toFloat() * .5f - iconSize / 2f - RGBAColor.WHITE.setSystemColor() - feature.renderIcon(event.guiGraphics, x, y, iconSize, iconSize) if (feature.isOnCooldown) { - RGBAColor.WHITE.setSystemColor() - val cooldownPct = feature.cooldownPercent if (cooldownPct > 0.0f) { - RenderSystem.setShaderColor(1f, 1f, 1f, 0.5f) - val nodrawpixels = (iconSize * (1 - cooldownPct)).roundToInt().toFloat() - drawRect(event.guiGraphics, x, y + nodrawpixels, iconSize, iconSize - nodrawpixels) - - RenderSystem.setShaderColor(1f, 1f, 1f, 1f) + event.guiGraphics.renderRect(x, y + nodrawpixels, iconSize, iconSize - nodrawpixels, color = RGBAColor.HALF_TRANSPARENT) } - Widgets18.COOLDOWN.render(event.guiGraphics, x, y + iconSize, iconSize, iconSize) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt index 53a4fc24d..11bd4aad9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/MatteryGUI.kt @@ -155,8 +155,12 @@ object MatteryGUI { pushScissorRect(0, (scissorBase + scissorHeight * (1f - progress)).toInt(), window.width, (scissorHeight * progress * 2f).toInt()) - setDrawColor(RGBAColor(1f, 1f, 1f, 0.4f)) - drawRect(event.guiGraphics, 0f, y - 12f, window.guiScaledWidth.toFloat(), 24f + (deathLog.size - 2f).coerceAtLeast(0f) * minecraft.font.lineHeight * modifyScale * 0.175f) + event.guiGraphics.renderRect( + 0f, + y - 12f, + window.guiScaledWidth.toFloat(), + 24f + (deathLog.size - 2f).coerceAtLeast(0f) * minecraft.font.lineHeight * modifyScale * 0.175f, + color = RGBAColor(1f, 1f, 1f, 0.4f)) val text = TranslatableComponent("otm.iteration", iteration) @@ -249,8 +253,8 @@ object MatteryGUI { val formattedPower = mattery.androidEnergy.batteryLevel.formatPower() - event.guiGraphics.drawScaledAligned(gui.font, formattedPower, 0.5f, RenderGravity.CENTER_LEFT, left + 83f, top + 4f, RGBAColor.BLACK.toInt()) - event.guiGraphics.drawScaledAligned(gui.font, formattedPower, 0.5f, RenderGravity.CENTER_LEFT, left + 82f, top + 3f, RGBAColor.YELLOW.toInt()) + event.guiGraphics.drawScaledAligned(gui.font, formattedPower, 0.5f, RenderGravity.CENTER_LEFT, left + 83f, top + 4f, RGBAColor.BLACK.toRGB()) + event.guiGraphics.drawScaledAligned(gui.font, formattedPower, 0.5f, RenderGravity.CENTER_LEFT, left + 82f, top + 3f, RGBAColor.YELLOW.toRGB()) } } @@ -268,14 +272,14 @@ object MatteryGUI { private fun getHealthColorForPlayer(player: Player): Int { if (player.hasEffect(MobEffects.POISON)) { - return RGBAColor.DARK_GREEN.toInt() + return RGBAColor.DARK_GREEN.toRGB() } else if (player.hasEffect(MobEffects.WITHER)) { - return RGBAColor.WHITE.toInt() + return RGBAColor.WHITE.toRGB() } else if (player.isFullyFrozen) { - return RGBAColor.AQUA.toInt() + return RGBAColor.AQUA.toRGB() } - return RGBAColor.RED.toInt() + return RGBAColor.RED.toRGB() } // можно вынести в конфиг, но для этого нужен селектор цвета private fun renderPlayerHealth(event: RenderGuiOverlayEvent.Pre, gui: ForgeGui) { @@ -325,7 +329,7 @@ object MatteryGUI { if (ply.absorptionAmount > 0) formattedHealth = "%d+%d/%d".format(ply.health.toInt(), ply.absorptionAmount.toInt(), ply.maxHealth.toInt()) - event.guiGraphics.drawScaledAligned(minecraft.font, formattedHealth, 0.5f, RenderGravity.CENTER_RIGHT, left - 4f, top + 4f, RGBAColor.BLACK.toInt()) + event.guiGraphics.drawScaledAligned(minecraft.font, formattedHealth, 0.5f, RenderGravity.CENTER_RIGHT, left - 4f, top + 4f, RGBAColor.BLACK.toRGB()) event.guiGraphics.drawScaledAligned(minecraft.font, formattedHealth, 0.5f, RenderGravity.CENTER_RIGHT, left - 5f, top + 3f, getHealthColorForPlayer(ply)) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/AbstractMatterySprite.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/AbstractMatterySprite.kt index 4b34ee8c4..d4ac1afef 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/AbstractMatterySprite.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/AbstractMatterySprite.kt @@ -17,7 +17,7 @@ import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.core.math.linearInterpolation import java.util.concurrent.ConcurrentHashMap -sealed class AbstractMatterySprite : IGUIRenderable { +sealed class AbstractMatterySprite : IGUIRenderable, IUVCoords { /** * Expected image width in pixels, used in calculations * and as default width argument in render methods @@ -30,11 +30,6 @@ sealed class AbstractMatterySprite : IGUIRenderable { */ abstract override val height: Float - abstract val u0: Float - abstract val v0: Float - abstract val u1: Float - abstract val v1: Float - fun partialU(offset: Float): Float { return u0 + (offset / width) * (u1 - u0) } @@ -44,9 +39,7 @@ sealed class AbstractMatterySprite : IGUIRenderable { } abstract val type: SpriteType - override val winding: UVWindingOrder get() = UVWindingOrder.NORMAL - abstract val texture: ResourceLocation /** @@ -60,7 +53,6 @@ sealed class AbstractMatterySprite : IGUIRenderable { height: Float = this.height, ) = ru.dbotthepony.mc.otm.client.render.clearDepth(graphics, x, y, width, height) - @JvmOverloads fun render( stack: PoseStack, x: Float = 0f, @@ -69,11 +61,7 @@ sealed class AbstractMatterySprite : IGUIRenderable { height: Float = this.height, winding: UVWindingOrder = this.winding ) { - RenderSystem.setShaderTexture(0, texture) - RenderSystem.enableBlend() - RenderSystem.defaultBlendFunc() - - renderRaw(stack, x, y, width, height, winding) + renderTexturedRect(stack.last().pose(), x, y, width, height, uvWinding = winding, uv = this, texture = texture) } override fun render( @@ -82,217 +70,44 @@ sealed class AbstractMatterySprite : IGUIRenderable { y: Float, width: Float, height: Float, - winding: UVWindingOrder + winding: UVWindingOrder, + color: RGBAColor ) { - render(guiGraphics.pose(), x, y, width, height, winding) + guiGraphics.renderTexturedRect(x, y, width, height, uvWinding = winding, color = color, texture = texture, uv = this) } - override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, gravity: RenderGravity, winding: UVWindingOrder) { - render(guiGraphics.pose(), x, y, width, height, winding) - } - - @JvmOverloads - fun render( - stack: PoseStack, - x: Double, - y: Double = 0.0, - width: Double = this.width.toDouble(), - height: Double = this.height.toDouble(), - winding: UVWindingOrder = this.winding - ) = render(stack, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), winding) - - @JvmOverloads fun renderPartial( stack: PoseStack, x: Float = 0f, y: Float = 0f, width: Float = this.width, height: Float = this.height, - winding: UVWindingOrder = this.winding + winding: UVWindingOrder = this.winding, + color: RGBAColor = RGBAColor.WHITE ) { - RenderSystem.setShaderTexture(0, texture) - RenderSystem.enableBlend() - RenderSystem.defaultBlendFunc() + val u1 = u0 + linearInterpolation(width / this.width, 0f, u1 - u0) + val v1 = v0 + linearInterpolation(height / this.height, 0f, v1 - v0) - renderRawPartial(stack, x, y, width, height, winding) - } + val winded = winding.translate(u0, v0, u1.coerceIn(0f, 1f), v1.coerceIn(0f, 1f)) - @JvmOverloads - fun renderPartial( - graphics: GuiGraphics, - x: Float = 0f, - y: Float = 0f, - width: Float = this.width, - height: Float = this.height, - winding: UVWindingOrder = this.winding - ) = renderPartial(graphics.pose(), x, y, width, height, winding) - - @JvmOverloads - fun renderPartial( - stack: PoseStack, - x: Double, - y: Double = 0.0, - width: Double = this.width.toDouble(), - height: Double = this.height.toDouble(), - winding: UVWindingOrder = this.winding - ) = renderPartial(stack, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), winding) - - @JvmOverloads - fun renderPartial( - graphics: GuiGraphics, - x: Double, - y: Double = 0.0, - width: Double = this.width.toDouble(), - height: Double = this.height.toDouble(), - winding: UVWindingOrder = this.winding - ) = renderPartial(graphics.pose(), x, y, width, height, winding) - - @JvmOverloads - fun renderWidth( - stack: PoseStack, - x: Float = 0f, - y: Float = 0f, - width: Float = this.width, - winding: UVWindingOrder = this.winding - ) = render(stack, x, y, width = width, winding = winding) - - @JvmOverloads - fun renderWidth( - graphics: GuiGraphics, - x: Float = 0f, - y: Float = 0f, - width: Float = this.width, - winding: UVWindingOrder = this.winding - ) = renderWidth(graphics.pose(), x, y, width, winding) - - @JvmOverloads - fun renderWidth( - stack: PoseStack, - x: Double, - y: Double = 0.0, - width: Double = this.width.toDouble(), - winding: UVWindingOrder = this.winding - ) = renderWidth(stack, x.toFloat(), y.toFloat(), width.toFloat(), winding) - - @JvmOverloads - fun renderWidth( - graphics: GuiGraphics, - x: Double, - y: Double = 0.0, - width: Double = this.width.toDouble(), - winding: UVWindingOrder = this.winding - ) = renderWidth(graphics.pose(), x, y, width, winding) - - @JvmOverloads - fun renderHeight( - stack: PoseStack, - x: Float = 0f, - y: Float = 0f, - height: Float = this.height, - winding: UVWindingOrder = this.winding - ) = render(stack, x, y, height = height, winding = winding) - - @JvmOverloads - fun renderHeight( - graphics: GuiGraphics, - x: Float = 0f, - y: Float = 0f, - height: Float = this.height, - winding: UVWindingOrder = this.winding - ) = renderHeight(graphics.pose(), x, y, height, winding) - - @JvmOverloads - fun renderHeight( - stack: PoseStack, - x: Double, - y: Double = 0.0, - height: Double = this.height.toDouble(), - winding: UVWindingOrder = this.winding - ) = renderHeight(stack, x.toFloat(), y.toFloat(), height.toFloat(), winding) - - @JvmOverloads - fun renderHeight( - graphics: GuiGraphics, - x: Double, - y: Double = 0.0, - height: Double = this.height.toDouble(), - winding: UVWindingOrder = this.winding - ) = renderHeight(graphics.pose(), x, y, height, winding) - - @JvmOverloads - fun renderRaw( - stack: PoseStack, - x: Float = 0f, - y: Float = 0f, - width: Float = this.width, - height: Float = this.height, - winding: UVWindingOrder = this.winding - ) { - val winded = winding.translate(u0, v0, u1, v1) - - drawTexturedRect( - stack, - x, - y, - width, - height, - winded, + renderTexturedRect( + stack.last().pose(), + x = x, y = y, + width = width, height = height, + uv = winded, texture = texture, + color = color ) } - @JvmOverloads - fun renderRaw( - stack: PoseStack, - x: Double, - y: Double = 0.0, - width: Double = this.width.toDouble(), - height: Double = this.height.toDouble(), - winding: UVWindingOrder = this.winding - ) = renderRaw(stack, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), winding) - - @JvmOverloads - fun renderRaw( + fun renderPartial( graphics: GuiGraphics, - x: Double, - y: Double = 0.0, - width: Double = this.width.toDouble(), - height: Double = this.height.toDouble(), - winding: UVWindingOrder = this.winding - ) = renderRaw(graphics.pose(), x, y, width, height, winding) - - @JvmOverloads - fun renderRawPartial( - stack: PoseStack, x: Float = 0f, y: Float = 0f, width: Float = this.width, height: Float = this.height, - winding: UVWindingOrder = this.winding - ) { - val u1 = (u0 + linearInterpolation(width / this.width, 0f, u1 - u0)).coerceAtLeast(0f).coerceAtMost(1f) - val v1 = (v0 + linearInterpolation(height / this.height, 0f, v1 - v0)).coerceAtLeast(0f).coerceAtMost(1f) - - val winded = winding.translate(u0, v0, u1, v1) - - drawTexturedRect( - stack, - x, - y, - width, - height, - winded, - ) - } - - @JvmOverloads - fun renderRawPartial( - stack: PoseStack, - x: Double, - y: Double = 0.0, - width: Double = this.width.toDouble(), - height: Double = this.height.toDouble(), - winding: UVWindingOrder = this.winding - ) = renderRawPartial(stack, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), winding) + winding: UVWindingOrder = this.winding, + color: RGBAColor = RGBAColor.WHITE + ) = renderPartial(graphics.pose(), x, y, width, height, winding, color) protected fun uploadOnto( pose: PoseStack, @@ -308,15 +123,13 @@ sealed class AbstractMatterySprite : IGUIRenderable { u1: Float, v1: Float, ) { - val intColor = color?.toARGB() ?: 0 val matrix = pose.last().pose() - builder.vertex(matrix, x, y + height, z).also { if (color != null) it.color(intColor) }.uv(u0, v1).endVertex() - builder.vertex(matrix, x + width, y + height, z).also { if (color != null) it.color(intColor) }.uv(u1, v1).endVertex() - builder.vertex(matrix, x + width, y, z).also { if (color != null) it.color(intColor) }.uv(u1, v0).endVertex() - builder.vertex(matrix, x, y, z).also { if (color != null) it.color(intColor) }.uv(u0, v0).endVertex() + builder.vertex(matrix, x, y + height, z).color(color).uv(u0, v1).endVertex() + builder.vertex(matrix, x + width, y + height, z).color(color).uv(u1, v1).endVertex() + builder.vertex(matrix, x + width, y, z).color(color).uv(u1, v0).endVertex() + builder.vertex(matrix, x, y, z).color(color).uv(u0, v0).endVertex() } - @JvmOverloads fun uploadOnto( pose: PoseStack, builder: VertexConsumer, @@ -328,11 +141,14 @@ sealed class AbstractMatterySprite : IGUIRenderable { color: RGBAColor? = null, winding: UVWindingOrder = this.winding, ) { - val (u0, v0, u1, v1) = winding.translate(u0, v0, u1, v1) + val u0 = winding.u0(this) + val v0 = winding.v0(this) + val u1 = winding.u1(this) + val v1 = winding.v1(this) + uploadOnto(pose, builder, x, y, width, height, z, color, u0, v0, u1, v1) } - @JvmOverloads fun uploadOntoPartial( pose: PoseStack, builder: VertexConsumer, @@ -351,36 +167,6 @@ sealed class AbstractMatterySprite : IGUIRenderable { uploadOnto(pose, builder, x, y, width, height, z, color, u0_, v0_, u1_, v1_) } - @JvmOverloads - fun uploadOntoPartialColor( - pose: PoseStack, - builder: VertexConsumer, - x: Float = 0f, - y: Float = 0f, - width: Float = this.width, - height: Float = this.height, - z: Float = 0f, - color: RGBAColor = RGBAColor.WHITE, - winding: UVWindingOrder = this.winding, - ) { - uploadOntoPartial(pose, builder, x, y, width, height, z, color, winding) - } - - @JvmOverloads - fun uploadOntoColor( - pose: PoseStack, - builder: VertexConsumer, - x: Float = 0f, - y: Float = 0f, - width: Float = this.width, - height: Float = this.height, - z: Float = 0f, - color: RGBAColor = RGBAColor.WHITE, - winding: UVWindingOrder = this.winding, - ) { - uploadOnto(pose, builder, x, y, width, height, z, color, winding) - } - fun toJson(): JsonObject { return type.toActualJson(this) } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Ext.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Ext.kt index fad69667b..fd3def77d 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Ext.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/Ext.kt @@ -25,7 +25,12 @@ val tesselator: Tesselator get() = Tesselator.getInstance() fun VertexConsumer.normal(vector: Vector): VertexConsumer = normal(vector.x.toFloat(), vector.y.toFloat(), vector.z.toFloat()) fun VertexConsumer.vertex(matrix4f: Matrix4f, vector: Vector): VertexConsumer = vertex(matrix4f, vector.x.toFloat(), vector.y.toFloat(), vector.z.toFloat()) -fun VertexConsumer.color(color: RGBAColor): VertexConsumer = color(color.red, color.green, color.blue, color.alpha) +fun VertexConsumer.color(color: RGBAColor?): VertexConsumer { + if (color != null) + color(color.redInt, color.greenInt, color.blueInt, color.alphaInt) + + return this +} fun PoseStack.translate(vector: Vector) = translate(vector.x, vector.y, vector.z) fun PoseStack.translate(vector: Vec3i) = translate(vector.x.toDouble(), vector.y.toDouble(), vector.z.toDouble()) @@ -217,46 +222,46 @@ fun Font.drawAligned(poseStack: PoseStack, text: String, align: RenderGravity, x fun Font.drawAligned(poseStack: PoseStack, text: Component, align: RenderGravity, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(poseStack, text, align, x, y, color) fun Font.drawAligned(poseStack: PoseStack, text: FormattedCharSequence, align: RenderGravity, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(poseStack, text, align, x, y, color) -fun Font.drawAligned(poseStack: PoseStack, text: String, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(poseStack, text, align, x, y, color.toInt()) -fun Font.drawAligned(poseStack: PoseStack, text: Component, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(poseStack, text, align, x, y, color.toInt()) -fun Font.drawAligned(poseStack: PoseStack, text: FormattedCharSequence, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(poseStack, text, align, x, y, color.toInt()) +fun Font.drawAligned(poseStack: PoseStack, text: String, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(poseStack, text, align, x, y, color.toRGB()) +fun Font.drawAligned(poseStack: PoseStack, text: Component, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(poseStack, text, align, x, y, color.toRGB()) +fun Font.drawAligned(poseStack: PoseStack, text: FormattedCharSequence, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(poseStack, text, align, x, y, color.toRGB()) fun Font.drawScaledAligned(poseStack: PoseStack, text: String, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(poseStack, text, scale, align, x, y, color) fun Font.drawScaledAligned(poseStack: PoseStack, text: Component, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(poseStack, text, scale, align, x, y, color) fun Font.drawScaledAligned(poseStack: PoseStack, text: FormattedCharSequence, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(poseStack, text, scale, align, x, y, color) -fun Font.drawScaledAligned(poseStack: PoseStack, text: String, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(poseStack, text, scale, align, x, y, color.toInt()) -fun Font.drawScaledAligned(poseStack: PoseStack, text: Component, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(poseStack, text, scale, align, x, y, color.toInt()) -fun Font.drawScaledAligned(poseStack: PoseStack, text: FormattedCharSequence, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(poseStack, text, scale, align, x, y, color.toInt()) +fun Font.drawScaledAligned(poseStack: PoseStack, text: String, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(poseStack, text, scale, align, x, y, color.toRGB()) +fun Font.drawScaledAligned(poseStack: PoseStack, text: Component, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(poseStack, text, scale, align, x, y, color.toRGB()) +fun Font.drawScaledAligned(poseStack: PoseStack, text: FormattedCharSequence, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(poseStack, text, scale, align, x, y, color.toRGB()) fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: String, align: RenderGravity, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAlignedDuckTyped(poseStack, buffer, text, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: Component, align: RenderGravity, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAlignedDuckTyped(poseStack, buffer, text, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: FormattedCharSequence, align: RenderGravity, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAlignedDuckTyped(poseStack, buffer, text, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor) -fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: String, align: RenderGravity, x: Float, y: Float, color: RGBAColor, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAligned(poseStack, buffer, text, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor) -fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: Component, align: RenderGravity, x: Float, y: Float, color: RGBAColor, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAligned(poseStack, buffer, text, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor) -fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: FormattedCharSequence, align: RenderGravity, x: Float, y: Float, color: RGBAColor, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAligned(poseStack, buffer, text, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor) +fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: String, align: RenderGravity, x: Float, y: Float, color: RGBAColor, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAligned(poseStack, buffer, text, align, x, y, color.toRGB(), drawShadow, displayMode, packedLightCoords, effectColor) +fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: Component, align: RenderGravity, x: Float, y: Float, color: RGBAColor, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAligned(poseStack, buffer, text, align, x, y, color.toRGB(), drawShadow, displayMode, packedLightCoords, effectColor) +fun Font.drawAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: FormattedCharSequence, align: RenderGravity, x: Float, y: Float, color: RGBAColor, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0) = drawAligned(poseStack, buffer, text, align, x, y, color.toRGB(), drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: String, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0,) = drawScaledAlignedDuckTyped(poseStack, buffer, text, scale, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: Component, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0,) = drawScaledAlignedDuckTyped(poseStack, buffer, text, scale, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor) fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: FormattedCharSequence, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0,) = drawScaledAlignedDuckTyped(poseStack, buffer, text, scale, align, x, y, color, drawShadow, displayMode, packedLightCoords, effectColor) -fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: String, scale: Float, align: RenderGravity, x: Float, y: Float, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0, color: RGBAColor) = drawScaledAligned(poseStack, buffer, text, scale, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor) -fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: Component, scale: Float, align: RenderGravity, x: Float, y: Float, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0, color: RGBAColor) = drawScaledAligned(poseStack, buffer, text, scale, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor) -fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: FormattedCharSequence, scale: Float, align: RenderGravity, x: Float, y: Float, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0, color: RGBAColor) = drawScaledAligned(poseStack, buffer, text, scale, align, x, y, color.toInt(), drawShadow, displayMode, packedLightCoords, effectColor) +fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: String, scale: Float, align: RenderGravity, x: Float, y: Float, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0, color: RGBAColor) = drawScaledAligned(poseStack, buffer, text, scale, align, x, y, color.toRGB(), drawShadow, displayMode, packedLightCoords, effectColor) +fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: Component, scale: Float, align: RenderGravity, x: Float, y: Float, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0, color: RGBAColor) = drawScaledAligned(poseStack, buffer, text, scale, align, x, y, color.toRGB(), drawShadow, displayMode, packedLightCoords, effectColor) +fun Font.drawScaledAligned(poseStack: PoseStack, buffer: MultiBufferSource, text: FormattedCharSequence, scale: Float, align: RenderGravity, x: Float, y: Float, drawShadow: Boolean = false, displayMode: Font.DisplayMode = Font.DisplayMode.NORMAL, packedLightCoords: Int = 15728880, effectColor: Int = 0, color: RGBAColor) = drawScaledAligned(poseStack, buffer, text, scale, align, x, y, color.toRGB(), drawShadow, displayMode, packedLightCoords, effectColor) fun GuiGraphics.drawAligned(font: Font, text: String, align: RenderGravity, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(font, text, align, x, y, color) fun GuiGraphics.drawAligned(font: Font, text: Component, align: RenderGravity, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(font, text, align, x, y, color) fun GuiGraphics.drawAligned(font: Font, text: FormattedCharSequence, align: RenderGravity, x: Float, y: Float, color: Int) = drawAlignedDuckTyped(font, text, align, x, y, color) -fun GuiGraphics.drawAligned(font: Font, text: String, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(font, text, align, x, y, color.toInt()) -fun GuiGraphics.drawAligned(font: Font, text: Component, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(font, text, align, x, y, color.toInt()) -fun GuiGraphics.drawAligned(font: Font, text: FormattedCharSequence, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(font, text, align, x, y, color.toInt()) +fun GuiGraphics.drawAligned(font: Font, text: String, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(font, text, align, x, y, color.toRGB()) +fun GuiGraphics.drawAligned(font: Font, text: Component, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(font, text, align, x, y, color.toRGB()) +fun GuiGraphics.drawAligned(font: Font, text: FormattedCharSequence, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawAligned(font, text, align, x, y, color.toRGB()) fun GuiGraphics.drawScaledAligned(font: Font, text: String, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(font, text, scale, align, x, y, color) fun GuiGraphics.drawScaledAligned(font: Font, text: Component, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(font, text, scale, align, x, y, color) fun GuiGraphics.drawScaledAligned(font: Font, text: FormattedCharSequence, scale: Float, align: RenderGravity, x: Float, y: Float, color: Int) = drawScaledAlignedDuckTyped(font, text, scale, align, x, y, color) -fun GuiGraphics.drawScaledAligned(font: Font, text: String, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(font, text, scale, align, x, y, color.toInt()) -fun GuiGraphics.drawScaledAligned(font: Font, text: Component, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(font, text, scale, align, x, y, color.toInt()) -fun GuiGraphics.drawScaledAligned(font: Font, text: FormattedCharSequence, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(font, text, scale, align, x, y, color.toInt()) +fun GuiGraphics.drawScaledAligned(font: Font, text: String, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(font, text, scale, align, x, y, color.toRGB()) +fun GuiGraphics.drawScaledAligned(font: Font, text: Component, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(font, text, scale, align, x, y, color.toRGB()) +fun GuiGraphics.drawScaledAligned(font: Font, text: FormattedCharSequence, scale: Float, align: RenderGravity, x: Float, y: Float, color: RGBAColor) = drawScaledAligned(font, text, scale, align, x, y, color.toRGB()) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/IGUIRenderable.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/IGUIRenderable.kt index 935dcac75..0f3da165c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/IGUIRenderable.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/IGUIRenderable.kt @@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.client.render import net.minecraft.client.gui.GuiGraphics import net.minecraft.world.item.ItemStack +import ru.dbotthepony.mc.otm.core.math.RGBAColor interface IGUIRenderable { /** @@ -19,14 +20,29 @@ interface IGUIRenderable { */ val winding: UVWindingOrder get() = UVWindingOrder.NORMAL - fun render(guiGraphics: GuiGraphics, x: Float = 0f, y: Float = 0f, gravity: RenderGravity = RenderGravity.TOP_LEFT, winding: UVWindingOrder = this.winding) { - render(guiGraphics, gravity.x(x, width), gravity.y(y, height), width, height, winding) + fun render( + guiGraphics: GuiGraphics, + x: Float = 0f, + y: Float = 0f, + gravity: RenderGravity = RenderGravity.TOP_LEFT, + winding: UVWindingOrder = this.winding, + color: RGBAColor = RGBAColor.WHITE, + ) { + render(guiGraphics, gravity.x(x, width), gravity.y(y, height), width, height, winding, color) } /** * Render at specified position [x], [y] with size of [width] x [height], optionally with UV [winding], if we are rendering flat texture/sprite */ - fun render(guiGraphics: GuiGraphics, x: Float = 0f, y: Float = 0f, width: Float = this.width, height: Float = this.height, winding: UVWindingOrder = this.winding) + fun render( + guiGraphics: GuiGraphics, + x: Float = 0f, + y: Float = 0f, + width: Float = this.width, + height: Float = this.height, + winding: UVWindingOrder = this.winding, + color: RGBAColor = RGBAColor.WHITE + ) fun composeBefore(other: IGUIRenderable): IGUIRenderable { return object : IGUIRenderable { @@ -35,9 +51,9 @@ interface IGUIRenderable { override val height: Float get() = this@IGUIRenderable.height.coerceAtLeast(other.height) - override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, winding: UVWindingOrder) { - this@IGUIRenderable.render(guiGraphics, x, y, width, height, winding) - other.render(guiGraphics, x, y, width, height, winding) + override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, winding: UVWindingOrder, color: RGBAColor) { + this@IGUIRenderable.render(guiGraphics, x, y, width, height, winding, color) + other.render(guiGraphics, x, y, width, height, winding, color) } } } @@ -53,8 +69,8 @@ interface IGUIRenderable { override val height: Float get() = this@IGUIRenderable.height - override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, winding: UVWindingOrder) { - this@IGUIRenderable.render(guiGraphics, x + left, y + top, width + right + left, height + bottom + top, winding) + override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, winding: UVWindingOrder, color: RGBAColor) { + this@IGUIRenderable.render(guiGraphics, x + left, y + top, width + right + left, height + bottom + top, winding, color) } } } @@ -76,7 +92,7 @@ interface IGUIRenderable { override val height: Float get() = this@IGUIRenderable.height - override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, winding: UVWindingOrder) { + override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, winding: UVWindingOrder, color: RGBAColor) { var realX = x var realY = y @@ -88,7 +104,7 @@ interface IGUIRenderable { realY += (height - this.height) / 2f } - this@IGUIRenderable.render(guiGraphics, realX, realY, if (fixedWidth) this.width else width, if (fixedHeight) this.height else height, if (fixedWinding) this.winding else winding) + this@IGUIRenderable.render(guiGraphics, realX, realY, if (fixedWidth) this.width else width, if (fixedHeight) this.height else height, if (fixedWinding) this.winding else winding, color) } } } @@ -105,7 +121,7 @@ interface IGUIRenderable { } data class ItemStackIcon(private val itemStack: ItemStack, override val width: Float = 16f, override val height: Float = 16f) : IGUIRenderable { - override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, winding: UVWindingOrder) { + override fun render(guiGraphics: GuiGraphics, x: Float, y: Float, width: Float, height: Float, winding: UVWindingOrder, color: RGBAColor) { if (x % 1f == 0f && y % 1f == 0f && width == 16f && height == 16f) { guiGraphics.renderFakeItem(itemStack, x.toInt(), y.toInt()) clearDepth(guiGraphics.pose(), x, y, width, height) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/MatterySprite.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/MatterySprite.kt index 867b6be9e..d561b8f4f 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/MatterySprite.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/MatterySprite.kt @@ -35,7 +35,7 @@ fun ResourceLocation.vLine( ) = MatterySprite(this, x, y, 1f, height, textureWidth, textureHeight) @Suppress("unused") -data class MatterySprite @JvmOverloads constructor( +class MatterySprite( override val texture: ResourceLocation, val x: Float, val y: Float, @@ -65,6 +65,16 @@ data class MatterySprite @JvmOverloads constructor( override val type: SpriteType get() = SpriteType.SINGLE + fun copy( + x: Float = this.x, + y: Float = this.y, + width: Float = this.width, + height: Float = this.height, + winding: UVWindingOrder = this.winding, + ): MatterySprite { + return MatterySprite(texture, x, y, width, height, atlasWidth, atlasHeight, winding) + } + companion object { fun single(texture: ResourceLocation, width: Float, height: Float, winding: UVWindingOrder = UVWindingOrder.NORMAL): MatterySprite { return MatterySprite(texture, 0f, 0f, width, height, width, height, winding) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt index 44cd9fcbb..84c95ceea 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/RenderHelper.kt @@ -9,6 +9,7 @@ import net.minecraft.client.renderer.RenderStateShard import net.minecraft.client.renderer.RenderStateShard.LineStateShard import net.minecraft.client.renderer.RenderType import net.minecraft.client.renderer.texture.TextureAtlasSprite +import net.minecraft.resources.ResourceLocation import org.joml.Matrix4f import org.lwjgl.opengl.GL11.GL_ALWAYS import org.lwjgl.opengl.GL11.GL_LESS @@ -23,10 +24,6 @@ import kotlin.math.pow import kotlin.math.roundToInt import kotlin.math.sin -private val identity = Matrix4f() - -var zLevel = 0f -var drawColor = RGBAColor(255, 255, 255, 255) var is3DContext = false /** @@ -36,24 +33,86 @@ var is3DContext = false */ var lockBlendFunc = false -@JvmName("setDrawColor\$JVM") -fun setDrawColor(color: RGBAColor) { - drawColor = color -} +private val defaultUV = UVCoords(0f, 0f, 1f, 1f) -// Regular functions -fun drawTexturedRect( +fun renderRect( matrix: Matrix4f, x: Float, y: Float, width: Float, height: Float, - u0: Float = 0f, - v0: Float = 0f, - u1: Float = 1f, - v1: Float = 1f + z: Float = 0f, + color: RGBAColor = RGBAColor.WHITE ) { - RenderSystem.setShader(GameRenderer::getPositionTexShader) + if (color.isWhite) + RenderSystem.setShader(GameRenderer::getPositionShader) + else + RenderSystem.setShader(GameRenderer::getPositionColorShader) + + RenderSystem.enableBlend() + RenderSystem.defaultBlendFunc() + + if (!is3DContext) + RenderSystem.depthFunc(GL_ALWAYS) + + val tess = tesselator + val builder = tess.builder + + if (color.isWhite) { + builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION) + + builder.vertex(matrix, x, y + height, z).endVertex() + builder.vertex(matrix, x + width, y + height, z).endVertex() + builder.vertex(matrix, x + width, y, z).endVertex() + builder.vertex(matrix, x, y, z).endVertex() + } else { + builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR) + + builder.vertex(matrix, x, y + height, z).color(color).endVertex() + builder.vertex(matrix, x + width, y + height, z).color(color).endVertex() + builder.vertex(matrix, x + width, y, z).color(color).endVertex() + builder.vertex(matrix, x, y, z).color(color).endVertex() + } + + tess.end() +} + +fun GuiGraphics.renderRect( + x: Float, + y: Float, + width: Float, + height: Float, + z: Float = 0f, + color: RGBAColor = RGBAColor.WHITE +) { + renderRect(pose().last().pose(), x, y, width, height, z, color) +} + +fun renderTexturedRect( + matrix: Matrix4f, + x: Float, + y: Float, + width: Float, + height: Float, + z: Float = 0f, + uv: IUVCoords = defaultUV, + uvWinding: UVWindingOrder = UVWindingOrder.NORMAL, + color: RGBAColor = RGBAColor.WHITE, + texture: ResourceLocation? = null +) { + val u0 = uvWinding.u0(uv) + val v0 = uvWinding.v0(uv) + val u1 = uvWinding.u1(uv) + val v1 = uvWinding.v1(uv) + + if (color.isWhite) + RenderSystem.setShader(GameRenderer::getPositionTexShader) + else + RenderSystem.setShader(GameRenderer::getPositionTexColorShader) + + if (texture != null) + RenderSystem.setShaderTexture(0, texture) + RenderSystem.enableBlend() RenderSystem.defaultBlendFunc() @@ -62,86 +121,40 @@ fun drawTexturedRect( val builder = tesselator.builder - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX) - builder.vertex(matrix, x, y + height, zLevel).uv(u0, v1).endVertex() - builder.vertex(matrix, x + width, y + height, zLevel).uv(u1, v1).endVertex() - builder.vertex(matrix, x + width, y, zLevel).uv(u1, v0).endVertex() - builder.vertex(matrix, x, y, zLevel).uv(u0, v0).endVertex() + if (color.isWhite) { + builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX) + + builder.vertex(matrix, x, y + height, z).uv(u0, v1).endVertex() + builder.vertex(matrix, x + width, y + height, z).uv(u1, v1).endVertex() + builder.vertex(matrix, x + width, y, z).uv(u1, v0).endVertex() + builder.vertex(matrix, x, y, z).uv(u0, v0).endVertex() + } else { + builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_TEX_COLOR) + + builder.vertex(matrix, x, y + height, z).uv(u0, v1).color(color).endVertex() + builder.vertex(matrix, x + width, y + height, z).uv(u1, v1).color(color).endVertex() + builder.vertex(matrix, x + width, y, z).uv(u1, v0).color(color).endVertex() + builder.vertex(matrix, x, y, z).uv(u0, v0).color(color).endVertex() + } BufferUploader.drawWithShader(builder.end()) } -fun drawTexturedRect( - matrix: Matrix4f, +fun GuiGraphics.renderTexturedRect( x: Float, y: Float, width: Float, height: Float, - uv: IUVCoords -) = drawTexturedRect(matrix, x, y, width, height, uv.u0, uv.v0, uv.u1, uv.v1) + z: Float = 0f, + uv: IUVCoords = defaultUV, + uvWinding: UVWindingOrder = UVWindingOrder.NORMAL, + color: RGBAColor = RGBAColor.WHITE, + texture: ResourceLocation? = null +) { + renderTexturedRect(pose().last().pose(), x, y, width, height, z, uv, uvWinding, color, texture) +} -fun drawTexturedRect( - stack: PoseStack, - x: Float, - y: Float, - width: Float, - height: Float, - uv: IUVCoords -) = drawTexturedRect(stack.last().pose(), x, y, width, height, uv.u0, uv.v0, uv.u1, uv.v1) - -fun drawTexturedRect( - graphics: GuiGraphics, - x: Float, - y: Float, - width: Float, - height: Float, - uv: IUVCoords -) = drawTexturedRect(graphics.pose(), x, y, width, height, uv) - -fun drawTexturedRect( - stack: PoseStack, - x: Float, - y: Float, - width: Float, - height: Float, - u0: Float, - v0: Float, - u1: Float, - v1: Float -) = drawTexturedRect(stack.last().pose(), x, y, width, height, u0, v0, u1, v1) - -fun drawTexturedRect( - graphics: GuiGraphics, - x: Float, - y: Float, - width: Float, - height: Float, - u0: Float, - v0: Float, - u1: Float, - v1: Float -) = drawTexturedRect(graphics.pose(), x, y, width, height, u0, v0, u1, v1) - -fun drawTexturedRect( - x: Float, - y: Float, - width: Float, - height: Float, - uv: IUVCoords -) = drawTexturedRect(identity, x, y, width, height, uv.u0, uv.v0, uv.u1, uv.v1) - -fun drawTexturedRect( - x: Float, - y: Float, - width: Float, - height: Float, - u0: Float, - v0: Float, - u1: Float, - v1: Float -) = drawTexturedRect(identity, x, y, width, height, u0, v0, u1, v1) - -fun colorSphere(matrix: Matrix4f, radius: Float) { +fun renderColoredSphere(pose: PoseStack, radius: Float, color: RGBAColor = RGBAColor.WHITE) { val fragments = 32 RenderSystem.enableBlend() RenderSystem.defaultBlendFunc() @@ -166,20 +179,20 @@ fun colorSphere(matrix: Matrix4f, radius: Float) { val yPre = (sin(tiltPre) + 0.5).toFloat() * radius val yPost = (sin(tiltPost) + 0.5).toFloat() * radius - builder.vertex(matrix, xPre * cos(tiltPost).toFloat(), yPost, zPre * cos(tiltPost).toFloat()) - .color(drawColor) + builder.vertex(pose.last().pose(), xPre * cos(tiltPost).toFloat(), yPost, zPre * cos(tiltPost).toFloat()) + .color(color) .endVertex() - builder.vertex(matrix, xPost * cos(tiltPost).toFloat(), yPost, zPost * cos(tiltPost).toFloat()) - .color(drawColor) + builder.vertex(pose.last().pose(), xPost * cos(tiltPost).toFloat(), yPost, zPost * cos(tiltPost).toFloat()) + .color(color) .endVertex() - builder.vertex(matrix, xPost * cos(tiltPre).toFloat(), yPre, zPost * cos(tiltPre).toFloat()) - .color(drawColor) + builder.vertex(pose.last().pose(), xPost * cos(tiltPre).toFloat(), yPre, zPost * cos(tiltPre).toFloat()) + .color(color) .endVertex() - builder.vertex(matrix, xPre * cos(tiltPre).toFloat(), yPre, zPre * cos(tiltPre).toFloat()) - .color(drawColor) + builder.vertex(pose.last().pose(), xPre * cos(tiltPre).toFloat(), yPre, zPre * cos(tiltPre).toFloat()) + .color(color) .endVertex() } } @@ -187,200 +200,6 @@ fun colorSphere(matrix: Matrix4f, radius: Float) { BufferUploader.drawWithShader(builder.end()) } -fun colorSphere(pose: PoseStack, radius: Float) = colorSphere(pose.last().pose(), radius) - -fun drawTexturedRectAuto( - stack: PoseStack, - x: Float, - y: Float, - width: Float, - height: Float, - image_x: Float, - image_y: Float, - mapped_width: Float, - mapped_height: Float -) = drawTexturedRect( - stack, - x, - y, - width, - height, - image_x / mapped_width, - image_y / mapped_height, - (image_x + width) / mapped_width, - (image_y + height) / mapped_height -) - -fun drawTexturedRectAuto( - stack: PoseStack, - x: Float, - y: Float, - width: Float, - height: Float, - image_x: Float, - image_y: Float, - mapped_width: Float, - mapped_height: Float, - order: UVWindingOrder -) = drawTexturedRect( - stack, - x, - y, - width, - height, - order.translate( - image_x / mapped_width, - image_y / mapped_height, - (image_x + width) / mapped_width, - (image_y + height) / mapped_height - ) -) - -fun drawTexturedRectAuto( - matrix: Matrix4f, - x: Float, - y: Float, - width: Float, - height: Float, - image_x: Float, - image_y: Float, - mapped_width: Float, - mapped_height: Float -) = drawTexturedRect( - matrix, - x, - y, - width, - height, - image_x / mapped_width, - image_y / mapped_height, - (image_x + width) / mapped_width, - (image_y + height) / mapped_height -) - -fun drawTexturedRectAuto( - matrix: Matrix4f, - x: Float, - y: Float, - width: Float, - height: Float, - image_x: Float, - image_y: Float, - mapped_width: Float, - mapped_height: Float, - order: UVWindingOrder -) = drawTexturedRect( - matrix, - x, - y, - width, - height, - order.translate( - image_x / mapped_width, - image_y / mapped_height, - (image_x + width) / mapped_width, - (image_y + height) / mapped_height - ) -) - - -fun drawTexturedRectAuto( - x: Float, - y: Float, - width: Float, - height: Float, - image_x: Float, - image_y: Float, - mapped_width: Float, - mapped_height: Float -) = drawTexturedRect( - x, - y, - width, - height, - image_x / mapped_width, - image_y / mapped_height, - (image_x + width) / mapped_width, - (image_y + height) / mapped_height -) - -fun drawTexturedRectAuto( - x: Float, - y: Float, - width: Float, - height: Float, - image_x: Float, - image_y: Float, - mapped_width: Float, - mapped_height: Float, - order: UVWindingOrder -) = drawTexturedRect( - x, - y, - width, - height, - order.translate( - image_x / mapped_width, - image_y / mapped_height, - (image_x + width) / mapped_width, - (image_y + height) / mapped_height - ) -) - -fun drawRect( - matrix: Matrix4f, - x: Float, - y: Float, - width: Float, - height: Float, - color: RGBAColor = drawColor -) { - RenderSystem.enableBlend() - RenderSystem.defaultBlendFunc() - RenderSystem.setShader(GameRenderer::getPositionColorShader) - - if (!is3DContext) - RenderSystem.depthFunc(GL_ALWAYS) - - val tess = tesselator - val builder = tess.builder - - builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION_COLOR) - - builder.vertex(matrix, x, y + height, zLevel).color(color).endVertex() - builder.vertex(matrix, x + width, y + height, zLevel).color(color).endVertex() - builder.vertex(matrix, x + width, y, zLevel).color(color).endVertex() - builder.vertex(matrix, x, y, zLevel).color(color).endVertex() - - tess.end() -} - -fun drawRect( - pose: PoseStack, - x: Float, - y: Float, - width: Float, - height: Float, - color: RGBAColor = drawColor -) = drawRect(pose.last().pose(), x, y, width, height, color = color) - -fun drawRect( - graphics: GuiGraphics, - x: Float, - y: Float, - width: Float, - height: Float, - color: RGBAColor = drawColor -) = drawRect(graphics.pose(), x, y, width, height, color = color) - -fun drawRect( - x: Float, - y: Float, - width: Float, - height: Float, - color: RGBAColor = drawColor -) = drawRect(identity, x, y, width, height, color = color) - fun drawLine( matrix: Matrix4f, startX: Float, @@ -388,11 +207,12 @@ fun drawLine( endX: Float, endY: Float, width: Float, - color: RGBAColor = drawColor + z: Float = 0f, + color: RGBAColor = RGBAColor.WHITE ) { + RenderSystem.setShader(GameRenderer::getPositionColorShader) RenderSystem.enableBlend() RenderSystem.defaultBlendFunc() - RenderSystem.setShader(GameRenderer::getPositionColorShader) if (!is3DContext) RenderSystem.depthFunc(GL_ALWAYS) @@ -421,54 +241,37 @@ fun drawLine( builder.vertex(matrix, startX - y0 * sin, startY + y0 * cos, - zLevel).color(color).endVertex() + z).color(color).endVertex() builder.vertex(matrix, startX - y1 * sin, startY + y1 * cos, - zLevel).color(color).endVertex() + z).color(color).endVertex() builder.vertex(matrix, startX + x2 * cos - y2 * sin, startY + x2 * sin + y2 * cos, - zLevel).color(color).endVertex() + z).color(color).endVertex() builder.vertex(matrix, startX + x3 * cos - y3 * sin, startY + x3 * sin + y3 * cos, - zLevel).color(color).endVertex() + z).color(color).endVertex() tess.end() } -fun drawLine( - pose: PoseStack, +fun GuiGraphics.drawLine( startX: Float, startY: Float, endX: Float, endY: Float, width: Float, - color: RGBAColor = drawColor -) = drawLine(pose.last().pose(), startX, startY, endX, endY, width, color = color) - -fun drawLine( - graphics: GuiGraphics, - startX: Float, - startY: Float, - endX: Float, - endY: Float, - width: Float, - color: RGBAColor = drawColor -) = drawLine(graphics.pose(), startX, startY, endX, endY, width, color = color) - -fun drawLine( - startX: Float, - startY: Float, - endX: Float, - endY: Float, - width: Float, - color: RGBAColor = drawColor -) = drawLine(identity, startX, startY, endX, endY, width, color = color) + z: Float = 0f, + color: RGBAColor = RGBAColor.WHITE +) { + drawLine(pose().last().pose(), startX, startY, endX, endY, width, z, color) +} data class ScissorRect(val x: Int, val y: Int, val width: Int, val height: Int) { fun withinBounds(x: Int, y: Int): Boolean { @@ -562,9 +365,9 @@ fun TextureAtlasSprite.render( RenderSystem.setShaderTexture(0, atlasLocation()) if (winding.isIdentity) { - drawTexturedRect(stack.last().pose(), x, y, width, height, u0, v0, u1, v1) + renderTexturedRect(stack.last().pose(), x, y, width, height, uv = UVCoords(u0, v0, u1, v1)) } else { - drawTexturedRect(stack.last().pose(), x, y, width, height, winding.translate(u0, v0, u1, v1)) + renderTexturedRect(stack.last().pose(), x, y, width, height, uv = winding.translate(u0, v0, u1, v1)) } } @@ -672,6 +475,7 @@ fun uploadArc( endDegree: Double = PI * 2.0, steps: Int = (outerRadius * (endDegree - startDegree) * 4.0).roundToInt().coerceAtLeast(12), alignAtCenter: Boolean = true, + z: Float = 0f, triangleFan: Boolean ) { require(startDegree < endDegree) { "Invalid arc degree range: $startDegree - $endDegree" } @@ -701,13 +505,13 @@ fun uploadArc( if (triangleFan) { val singleStep = (endDegree - startDegree) / steps - builder.vertex(matrix, x, y, zLevel).endVertex() + builder.vertex(matrix, x, y, z).endVertex() for (i in 0 .. steps) { val sin = sin(startDegree + i * singleStep).toFloat() val cos = cos(startDegree + i * singleStep).toFloat() - builder.vertex(matrix, x + outerRadius * sin, y + cos * outerRadius, zLevel).endVertex() + builder.vertex(matrix, x + outerRadius * sin, y + cos * outerRadius, z).endVertex() } } else { val singleStep = (endDegree - startDegree) / (steps + 1) @@ -719,10 +523,10 @@ fun uploadArc( val sin2 = sin(startDegree + (i + 1) * singleStep).toFloat() val cos2 = cos(startDegree + (i + 1) * singleStep).toFloat() - builder.vertex(matrix, x + outerRadius * sin, y + cos * outerRadius, zLevel).endVertex() - builder.vertex(matrix, x + outerRadius * sin2, y + cos2 * outerRadius, zLevel).endVertex() - builder.vertex(matrix, x + innerRadius * sin2, y + cos2 * innerRadius, zLevel).endVertex() - builder.vertex(matrix, x + innerRadius * sin, y + cos * innerRadius, zLevel).endVertex() + builder.vertex(matrix, x + outerRadius * sin, y + cos * outerRadius, z).endVertex() + builder.vertex(matrix, x + outerRadius * sin2, y + cos2 * outerRadius, z).endVertex() + builder.vertex(matrix, x + innerRadius * sin2, y + cos2 * innerRadius, z).endVertex() + builder.vertex(matrix, x + innerRadius * sin, y + cos * innerRadius, z).endVertex() } } } @@ -736,7 +540,8 @@ fun drawArc( startDegree: Double = 0.0, endDegree: Double = PI * 2.0, steps: Int = (outerRadius * (endDegree - startDegree) * 4.0).roundToInt().coerceAtLeast(12), - alignAtCenter: Boolean = true + alignAtCenter: Boolean = true, + z: Float = 0f ) { require(startDegree < endDegree) { "Invalid arc degree range: $startDegree - $endDegree" } require(steps >= 0) { "Invalid amount of arc steps: $steps" } @@ -752,12 +557,12 @@ fun drawArc( if (innerRadius == 0f) { if (steps >= 1) { builder.begin(VertexFormat.Mode.TRIANGLE_FAN, DefaultVertexFormat.POSITION) - uploadArc(matrix, builder, x, y, outerRadius, innerRadius, startDegree, endDegree, steps, alignAtCenter, triangleFan = true) + uploadArc(matrix, builder, x, y, outerRadius, innerRadius, startDegree, endDegree, steps, alignAtCenter, triangleFan = true, z = z) BufferUploader.drawWithShader(builder.end()) } } else { builder.begin(VertexFormat.Mode.QUADS, DefaultVertexFormat.POSITION) - uploadArc(matrix, builder, x, y, outerRadius, innerRadius, startDegree, endDegree, steps, alignAtCenter, triangleFan = false) + uploadArc(matrix, builder, x, y, outerRadius, innerRadius, startDegree, endDegree, steps, alignAtCenter, triangleFan = false, z = z) BufferUploader.drawWithShader(builder.end()) } } @@ -804,20 +609,3 @@ val linesIgnoreZRenderType by lazy { .createCompositeState(false) ) as RenderType } - -fun VertexConsumer.quad( - pose: PoseStack, - x: Float, - y: Float, - width: Float, - height: Float, - z: Float, - color: RGBAColor? = null, -) { - val intColor = color?.toARGB() ?: 0 - val matrix = pose.last().pose() - vertex(matrix, x, y + height, z).also { if (color != null) it.color(intColor) }.endVertex() - vertex(matrix, x + width, y + height, z).also { if (color != null) it.color(intColor) }.endVertex() - vertex(matrix, x + width, y, z).also { if (color != null) it.color(intColor) }.endVertex() - vertex(matrix, x, y, z).also { if (color != null) it.color(intColor) }.endVertex() -} diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/UVStuff.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/UVStuff.kt index 406e8fec9..b71b9d1c7 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/UVStuff.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/UVStuff.kt @@ -1,34 +1,47 @@ package ru.dbotthepony.mc.otm.client.render -import com.google.common.collect.ImmutableList - -sealed interface IUVCoords { +interface IUVCoords { val u0: Float val v0: Float val u1: Float val v1: Float - operator fun get(index: Int): Float + + operator fun component1() = u0 + operator fun component2() = v0 + operator fun component3() = u1 + operator fun component4() = v1 + + fun getUV(index: Int): Float { + return when (index) { + 0 -> u0 + 1 -> v0 + 2 -> u1 + 3 -> v1 + else -> throw IndexOutOfBoundsException("$index") + } + } } -private val mapImmutable = ArrayList<(input: UVCoords) -> Float>() +private fun interface FlatGetter { + operator fun get(u0: Float, v0: Float, u1: Float, v1: Float): Float +} + +private fun interface RegularGetter { + operator fun get(input: IUVCoords): Float +} + +private val getters = ArrayList() .also { it.add { it.u0 } } .also { it.add { it.v0 } } .also { it.add { it.u1 } } .also { it.add { it.v1 } } .toTypedArray() -private val mapMutable = ArrayList<(input: MutableUVCoords) -> Float>() - .also { it.add { it.u0 } } - .also { it.add { it.v0 } } - .also { it.add { it.u1 } } - .also { it.add { it.v1 } } - .toTypedArray() - -private val mapSetMutable = ArrayList<(input: MutableUVCoords, value: Float) -> Unit>() - .also { it.add { input, value -> input.u0 = value } } - .also { it.add { input, value -> input.v0 = value } } - .also { it.add { input, value -> input.u1 = value } } - .also { it.add { input, value -> input.v1 = value } } +private val flatGetters = ArrayList() + .also { it.add { u0, _, _, _ -> u0 } } + .also { it.add { _, v0, _, _ -> v0 } } + .also { it.add { _, _, u1, _ -> u1 } } + .also { it.add { _, _, _, v1 -> v1 } } .toTypedArray() data class UVCoords( @@ -36,43 +49,16 @@ data class UVCoords( override val v0: Float, override val u1: Float, override val v1: Float, -) : IUVCoords { - override fun get(index: Int): Float { - return mapImmutable[index].invoke(this) - } -} +) : IUVCoords data class MutableUVCoords( override var u0: Float, override var v0: Float, override var u1: Float, override var v1: Float, -) : IUVCoords { - override fun get(index: Int): Float { - return mapMutable[index].invoke(this) - } +) : IUVCoords - operator fun set(index: Int, value: Float) { - mapSetMutable[index].invoke(this, value) - } -} - -private val pickers = ArrayList<(u0: Float, - v0: Float, - u1: Float, - v1: Float) -> Float>() - .also { it.add { u0, _, _, _ -> u0 } } - .also { it.add { _, v0, _, _ -> v0 } } - .also { it.add { _, _, u1, _ -> u1 } } - .also { it.add { _, _, _, v1 -> v1 } } - .toTypedArray() - -enum class UVWindingOrder( - val u0: Int, - val v0: Int, - val u1: Int, - val v1: Int, -) { +enum class UVWindingOrder(val u0: Int, val v0: Int, val u1: Int, val v1: Int) { NORMAL(0, 1, 2, 3), // normal operation U0_V0_U1_V1(0, 1, 2, 3), // normal operation U0_V1_U1_V0(0, 3, 2, 1), // mirror y @@ -82,10 +68,6 @@ enum class UVWindingOrder( U1_V1_U0_V0(2, 3, 0, 1), // mirror both FLIP_FLOP(2, 3, 0, 1); // mirror both - companion object { - val distinct: List = ImmutableList.of(NORMAL, FLIP, FLOP, FLIP_FLOP) - } - val isIdentity: Boolean = u0 == 0 && v0 == 1 && u1 == 2 && v1 == 3 operator fun component1() = u0 @@ -93,57 +75,55 @@ enum class UVWindingOrder( operator fun component3() = u1 operator fun component4() = v1 - val u0Picker = pickers[u0] - val v0Picker = pickers[v0] - val u1Picker = pickers[u1] - val v1Picker = pickers[v1] + private val u0FlatGetter = flatGetters[u0] + private val v0FlatGetter = flatGetters[v0] + private val u1FlatGetter = flatGetters[u1] + private val v1FlatGetter = flatGetters[v1] - private val buffer = FloatArray(4) + private val u0Getter = getters[u0] + private val v0Getter = getters[v0] + private val u1Getter = getters[u1] + private val v1Getter = getters[v1] - fun translate( - u0: Float, - v0: Float, - u1: Float, - v1: Float, - ): UVCoords { - synchronized(buffer) { - buffer[0] = u0 - buffer[1] = v0 - buffer[2] = u1 - buffer[3] = v1 + fun u0(u0: Float, v0: Float, u1: Float, v1: Float): Float = u0FlatGetter[u0, v0, u1, v1] + fun v0(u0: Float, v0: Float, u1: Float, v1: Float): Float = v0FlatGetter[u0, v0, u1, v1] + fun u1(u0: Float, v0: Float, u1: Float, v1: Float): Float = u1FlatGetter[u0, v0, u1, v1] + fun v1(u0: Float, v0: Float, u1: Float, v1: Float): Float = v1FlatGetter[u0, v0, u1, v1] - return UVCoords(buffer[this.u0], buffer[this.v0], buffer[this.u1], buffer[this.v1]) - } + fun u0(input: IUVCoords): Float = u0Getter[input] + fun v0(input: IUVCoords): Float = v0Getter[input] + fun u1(input: IUVCoords): Float = u1Getter[input] + fun v1(input: IUVCoords): Float = v1Getter[input] + + fun translate(u0: Float, v0: Float, u1: Float, v1: Float): IUVCoords { + return UVCoords( + u0FlatGetter[u0, v0, u1, v1], + v0FlatGetter[u0, v0, u1, v1], + u1FlatGetter[u0, v0, u1, v1], + v1FlatGetter[u0, v0, u1, v1] + ) } - fun translate( - input: UVCoords - ): UVCoords { - synchronized(buffer) { - buffer[0] = input.u0 - buffer[1] = input.v0 - buffer[2] = input.u1 - buffer[3] = input.v1 - - return UVCoords(buffer[this.u0], buffer[this.v0], buffer[this.u1], buffer[this.v1]) - } + fun translate(input: IUVCoords): IUVCoords { + return UVCoords( + u0Getter[input], + v0Getter[input], + u1Getter[input], + v1Getter[input], + ) } - fun translate( - input: MutableUVCoords - ): MutableUVCoords { - synchronized(buffer) { - buffer[0] = input.u0 - buffer[1] = input.v0 - buffer[2] = input.u1 - buffer[3] = input.v1 + fun translate(input: MutableUVCoords): MutableUVCoords { + val u0 = u0(input) + val v0 = v0(input) + val u1 = u1(input) + val v1 = v1(input) - input[0] = buffer[this.u0] - input[1] = buffer[this.v0] - input[2] = buffer[this.u1] - input[3] = buffer[this.v1] + input.u0 = u0 + input.v0 = v0 + input.u1 = u1 + input.v1 = v1 - return input - } + return input } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BankRenderer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BankRenderer.kt index bc4e42e8d..cd8a147de 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BankRenderer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BankRenderer.kt @@ -22,6 +22,7 @@ import ru.dbotthepony.mc.otm.client.screen.widget.PowerGaugePanel import ru.dbotthepony.mc.otm.core.immutableList import ru.dbotthepony.mc.otm.core.get import ru.dbotthepony.mc.otm.core.math.BlockRotationFreedom +import ru.dbotthepony.mc.otm.core.math.RGBAColor import ru.dbotthepony.mc.otm.core.math.facingOne import ru.dbotthepony.mc.otm.core.math.rotate import ru.dbotthepony.mc.otm.core.math.rotateY @@ -91,25 +92,27 @@ abstract class BankRenderer(private val context: B val buffer = DynamicBufferSource.WORLD.getBuffer(texture.renderTypeWorld) - texture.uploadOntoPartialColor( + texture.uploadOntoPartial( stack, buffer, x = 25f - width / 2f, y = 30f, width = width, - height = heightMax * gaugeLevel(blockEntity) + height = heightMax * gaugeLevel(blockEntity), + color = RGBAColor.WHITE ) stack.rotateY(PI.toFloat()) stack.translate(-50.0, 0.0, -101.0) - texture.uploadOntoPartialColor( + texture.uploadOntoPartial( stack, buffer, x = 25f - width / 2f, y = 30f, width = width, - height = heightMax * gaugeLevel(blockEntity) + height = heightMax * gaugeLevel(blockEntity), + color = RGBAColor.WHITE ) stack.popPose() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BlackHoleRenderer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BlackHoleRenderer.kt index a5ad2be22..efd6fcea3 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BlackHoleRenderer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/BlackHoleRenderer.kt @@ -105,7 +105,6 @@ class BlackHoleRenderer(private val context: BlockEntityRendererProvider.Context i: Int, i1: Int ) { - setDrawColor(RGBAColor.BLACK) RenderSystem.setShader(GameRenderer::getPositionColorShader) RenderSystem.depthFunc(GL30.GL_LESS) @@ -116,7 +115,7 @@ class BlackHoleRenderer(private val context: BlockEntityRendererProvider.Context poseStack.pushPose() val size = tile.gravitationStrength.pow(0.5) poseStack.translate(0.5, -size / 2.0 + 0.5, 0.5) - colorSphere(poseStack, size.toFloat()) + renderColoredSphere(poseStack, size.toFloat(), color = RGBAColor.BLACK) RenderSystem.enableCull() diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/HoloSignRenderer.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/HoloSignRenderer.kt index 32994e002..465db9cf5 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/HoloSignRenderer.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/render/blockentity/HoloSignRenderer.kt @@ -37,7 +37,7 @@ class HoloSignRenderer(private val context: BlockEntityRendererProvider.Context) var y = -totalHeight / 2f for (line in lines) { - font.drawAligned(poseStack = poseStack, buffer = sorse, text = line, align = RenderGravity.TOP_CENTER, x = 0f, y = y, color = RGBAColor.YELLOW.toInt()) + font.drawAligned(poseStack = poseStack, buffer = sorse, text = line, align = RenderGravity.TOP_CENTER, x = 0f, y = y, color = RGBAColor.YELLOW.toRGB()) y += font.lineHeight + 2f } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/FramePanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/FramePanel.kt index 58b1be9c0..cfd032691 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/FramePanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/FramePanel.kt @@ -65,10 +65,10 @@ open class FramePanel( TAB_BACKGROUND.render(graphics, 2f, 2f, width - 4, height - 2) } - RECTANGLE.top.renderWidth(graphics, 3f, 0f, width - 6) - RECTANGLE.left.renderHeight(graphics, 0f, 3f, (height - if (isActive) if (initial) 2 else 4 else 3)) + RECTANGLE.top.render(graphics, 3f, 0f, width = width - 6) + RECTANGLE.left.render(graphics, 0f, 3f, height = (height - if (isActive) if (initial) 2 else 4 else 3)) - RECTANGLE.right.renderHeight(graphics, width - RECTANGLE.right.width, 3f, (height - if (isActive) 4 else 3)) + RECTANGLE.right.render(graphics, width - RECTANGLE.right.width, 3f, height = (height - if (isActive) 4 else 3)) RECTANGLE.topLeft.render(graphics, 0f, 0f) RECTANGLE.topRight.render(graphics, width - RECTANGLE.topRight.width, 0f) diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/Label.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/Label.kt index b21085fd3..95e017ac9 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/Label.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/Label.kt @@ -36,28 +36,28 @@ open class Label @JvmOverloads constructor( if (shadow) { when (align) { - RenderGravity.TOP_LEFT -> graphics.drawAligned(font, text, align, shadowX, shadowY, shadowColor.toInt()) - RenderGravity.TOP_CENTER -> graphics.drawAligned(font, text, align, shadowX + width / 2f, shadowY, shadowColor.toInt()) - RenderGravity.TOP_RIGHT -> graphics.drawAligned(font, text, align, shadowX + width, shadowY, shadowColor.toInt()) - RenderGravity.CENTER_LEFT -> graphics.drawAligned(font, text, align, shadowX, height / 2f + shadowY, shadowColor.toInt()) - RenderGravity.CENTER_CENTER -> graphics.drawAligned(font, text, align, shadowX + width / 2f, height / 2f + shadowY, shadowColor.toInt()) - RenderGravity.CENTER_RIGHT -> graphics.drawAligned(font, text, align, shadowX + width, height / 2f + shadowY, shadowColor.toInt()) - RenderGravity.BOTTOM_LEFT -> graphics.drawAligned(font, text, align, shadowX, height + shadowY, shadowColor.toInt()) - RenderGravity.BOTTOM_CENTER -> graphics.drawAligned(font, text, align, shadowX + width / 2f, height + shadowY, shadowColor.toInt()) - RenderGravity.BOTTOM_RIGHT -> graphics.drawAligned(font, text, align, shadowX + width, height + shadowY, shadowColor.toInt()) + RenderGravity.TOP_LEFT -> graphics.drawAligned(font, text, align, shadowX, shadowY, shadowColor.toRGB()) + RenderGravity.TOP_CENTER -> graphics.drawAligned(font, text, align, shadowX + width / 2f, shadowY, shadowColor.toRGB()) + RenderGravity.TOP_RIGHT -> graphics.drawAligned(font, text, align, shadowX + width, shadowY, shadowColor.toRGB()) + RenderGravity.CENTER_LEFT -> graphics.drawAligned(font, text, align, shadowX, height / 2f + shadowY, shadowColor.toRGB()) + RenderGravity.CENTER_CENTER -> graphics.drawAligned(font, text, align, shadowX + width / 2f, height / 2f + shadowY, shadowColor.toRGB()) + RenderGravity.CENTER_RIGHT -> graphics.drawAligned(font, text, align, shadowX + width, height / 2f + shadowY, shadowColor.toRGB()) + RenderGravity.BOTTOM_LEFT -> graphics.drawAligned(font, text, align, shadowX, height + shadowY, shadowColor.toRGB()) + RenderGravity.BOTTOM_CENTER -> graphics.drawAligned(font, text, align, shadowX + width / 2f, height + shadowY, shadowColor.toRGB()) + RenderGravity.BOTTOM_RIGHT -> graphics.drawAligned(font, text, align, shadowX + width, height + shadowY, shadowColor.toRGB()) } } when (align) { - RenderGravity.TOP_LEFT -> font.drawAligned(graphics.pose(), text, align, 0f, 0f, color.toInt()) - RenderGravity.TOP_CENTER -> font.drawAligned(graphics.pose(), text, align, width / 2f, 0f, color.toInt()) - RenderGravity.TOP_RIGHT -> font.drawAligned(graphics.pose(), text, align, width - (if (shadow) shadowX else 0f), 0f, color.toInt()) - RenderGravity.CENTER_LEFT -> font.drawAligned(graphics.pose(), text, align, 0f, height / 2f, color.toInt()) - RenderGravity.CENTER_CENTER -> font.drawAligned(graphics.pose(), text, align, width / 2f, height / 2f, color.toInt()) - RenderGravity.CENTER_RIGHT -> font.drawAligned(graphics.pose(), text, align, width - (if (shadow) shadowX else 0f), height / 2f, color.toInt()) - RenderGravity.BOTTOM_LEFT -> font.drawAligned(graphics.pose(), text, align, 0f, height, color.toInt()) - RenderGravity.BOTTOM_CENTER -> font.drawAligned(graphics.pose(), text, align, width / 2f, height, color.toInt()) - RenderGravity.BOTTOM_RIGHT -> font.drawAligned(graphics.pose(), text, align, width - (if (shadow) shadowX else 0f), height, color.toInt()) + RenderGravity.TOP_LEFT -> font.drawAligned(graphics.pose(), text, align, 0f, 0f, color.toRGB()) + RenderGravity.TOP_CENTER -> font.drawAligned(graphics.pose(), text, align, width / 2f, 0f, color.toRGB()) + RenderGravity.TOP_RIGHT -> font.drawAligned(graphics.pose(), text, align, width - (if (shadow) shadowX else 0f), 0f, color.toRGB()) + RenderGravity.CENTER_LEFT -> font.drawAligned(graphics.pose(), text, align, 0f, height / 2f, color.toRGB()) + RenderGravity.CENTER_CENTER -> font.drawAligned(graphics.pose(), text, align, width / 2f, height / 2f, color.toRGB()) + RenderGravity.CENTER_RIGHT -> font.drawAligned(graphics.pose(), text, align, width - (if (shadow) shadowX else 0f), height / 2f, color.toRGB()) + RenderGravity.BOTTOM_LEFT -> font.drawAligned(graphics.pose(), text, align, 0f, height, color.toRGB()) + RenderGravity.BOTTOM_CENTER -> font.drawAligned(graphics.pose(), text, align, width / 2f, height, color.toRGB()) + RenderGravity.BOTTOM_RIGHT -> font.drawAligned(graphics.pose(), text, align, width - (if (shadow) shadowX else 0f), height, color.toRGB()) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/ButtonPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/ButtonPanel.kt index 94e07f8d9..c885d244e 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/ButtonPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/button/ButtonPanel.kt @@ -53,7 +53,7 @@ open class ButtonPanel( override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { renderStretchableBackground(graphics, mouseX, mouseY, partialTick) - graphics.drawAligned(font, label, RenderGravity.CENTER_CENTER, width / 2f, height / 2f, textColor.toInt()) + graphics.drawAligned(font, label, RenderGravity.CENTER_CENTER, width / 2f, height / 2f, textColor.toRGB()) } override fun sizeToContents() { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/TextInputPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/TextInputPanel.kt index c4372fe51..fb9d10ba8 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/TextInputPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/input/TextInputPanel.kt @@ -21,7 +21,7 @@ import ru.dbotthepony.mc.otm.client.playGuiClickSound import ru.dbotthepony.mc.otm.client.render.DynamicBufferSource import ru.dbotthepony.mc.otm.client.render.RenderGravity import ru.dbotthepony.mc.otm.client.render.drawAligned -import ru.dbotthepony.mc.otm.client.render.drawRect +import ru.dbotthepony.mc.otm.client.render.renderRect import ru.dbotthepony.mc.otm.client.render.tesselator import ru.dbotthepony.mc.otm.client.screen.panels.DockProperty import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel @@ -1073,7 +1073,7 @@ open class TextInputPanel( override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { if (!backgroundColor.isFullyTransparent) - drawRect(graphics, 0f, 0f, width, height, backgroundColor) + graphics.renderRect(0f, 0f, width, height, color = backgroundColor) var topPadding = dockPadding.top diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/AbstractSlotPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/AbstractSlotPanel.kt index 61866d64f..2b6bb7c4a 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/AbstractSlotPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/AbstractSlotPanel.kt @@ -38,8 +38,7 @@ abstract class AbstractSlotPanel> @JvmOverloads constru } if (isHovered) { - drawColor = SLOT_HIGHLIGHT - drawRect(graphics, 1f, 1f, width - 1, height - 1) + graphics.renderRect(1f, 1f, width - 1, height - 1, color = SLOT_HIGHLIGHT) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/SlotPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/SlotPanel.kt index 509a530d6..d2402e13b 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/SlotPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/SlotPanel.kt @@ -11,8 +11,7 @@ import net.minecraft.world.inventory.Slot import net.minecraft.world.item.ItemStack import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.render.Widgets18 -import ru.dbotthepony.mc.otm.client.render.drawRect -import ru.dbotthepony.mc.otm.client.render.setDrawColor +import ru.dbotthepony.mc.otm.client.render.renderRect import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel import ru.dbotthepony.mc.otm.client.screen.panels.ISlotPanel @@ -92,8 +91,7 @@ open class SlotPanel, out T : Slot> @JvmOverloads const RenderSystem.setShader(GameRenderer::getPositionTexShader) if (dragHit) { - setDrawColor(SLOT_HIGHLIGHT_DRAG) - drawRect(graphics, 1f, 1f, width - 1, height - 1) + graphics.renderRect(1f, 1f, width - 1, height - 1, color = SLOT_HIGHLIGHT_DRAG) } if (itemstack.isEmpty) { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/UserFilteredSlotPanel.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/UserFilteredSlotPanel.kt index efdaea426..7c9ce2e35 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/UserFilteredSlotPanel.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/panels/slot/UserFilteredSlotPanel.kt @@ -1,7 +1,6 @@ package ru.dbotthepony.mc.otm.client.screen.panels.slot import com.mojang.blaze3d.platform.InputConstants -import com.mojang.blaze3d.vertex.PoseStack import net.minecraft.ChatFormatting import net.minecraft.client.gui.GuiGraphics import net.minecraft.network.chat.Component @@ -13,9 +12,7 @@ import net.minecraftforge.client.extensions.common.IClientItemExtensions import ru.dbotthepony.mc.otm.client.isCtrlDown import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.playGuiClickSound -import ru.dbotthepony.mc.otm.client.render.MatterySprite -import ru.dbotthepony.mc.otm.client.render.drawColor -import ru.dbotthepony.mc.otm.client.render.drawRect +import ru.dbotthepony.mc.otm.client.render.renderRect import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel import ru.dbotthepony.mc.otm.core.GetterSetter @@ -49,12 +46,10 @@ abstract class UserFilteredSlotPanel, out T : Slot>( screen.renderItemStack(graphics, itemStack, null) clearDepth(graphics) - drawColor = SLOT_FILTER_COLOR + graphics.renderRect(0f, 0f, width, height, color = SLOT_FILTER_COLOR) } else { - drawColor = SLOT_BLOCK_COLOR + graphics.renderRect(0f, 0f, width, height, color = SLOT_BLOCK_COLOR) } - - drawRect(graphics, 0f, 0f, width, height) } } diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidStationScreen.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidStationScreen.kt index 7d51e8a86..edd721913 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidStationScreen.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/client/screen/tech/AndroidStationScreen.kt @@ -21,9 +21,8 @@ import ru.dbotthepony.mc.otm.client.minecraft import ru.dbotthepony.mc.otm.client.playGuiClickSound import ru.dbotthepony.mc.otm.client.render.RenderGravity import ru.dbotthepony.mc.otm.client.render.Widgets18 -import ru.dbotthepony.mc.otm.client.render.drawColor import ru.dbotthepony.mc.otm.client.render.drawLine -import ru.dbotthepony.mc.otm.client.render.drawRect +import ru.dbotthepony.mc.otm.client.render.renderRect import ru.dbotthepony.mc.otm.client.screen.MatteryScreen import ru.dbotthepony.mc.otm.client.screen.panels.* import ru.dbotthepony.mc.otm.client.screen.panels.button.ButtonPanel @@ -293,26 +292,24 @@ private class AndroidResearchButton( val isBlockedByHovered = hovered != null && node.type in hovered.type.allBlocking if (isBlockedByHovered) { - AndroidStationScreen.CAN_NOT_BE_RESEARCHED.setSystemColor() - - drawRect(graphics, 0f, 0f, width, height) + graphics.renderRect(0f, 0f, width, height, color = AndroidStationScreen.CAN_NOT_BE_RESEARCHED) } - if (node.isResearched) { - AndroidStationScreen.RESEARCHED.setSystemColor() + val nodeColor = if (node.isResearched) { + AndroidStationScreen.RESEARCHED } else if (node.isAnyBlockerResearchedIndirect) { - AndroidStationScreen.ALREADY_BLOCKED.setSystemColor() + AndroidStationScreen.ALREADY_BLOCKED } else if (node.canResearch) { - AndroidStationScreen.CAN_BE_RESEARCHED.setSystemColor() + AndroidStationScreen.CAN_BE_RESEARCHED } else { - AndroidStationScreen.CAN_NOT_BE_RESEARCHED.setSystemColor() + AndroidStationScreen.CAN_NOT_BE_RESEARCHED } val icon = node.type.resolvedSkinIcon val itemIcon = node.type.itemIcon if (icon != null) { - icon.render(graphics, 0f, 0f, width, height) + icon.render(graphics, 0f, 0f, width, height, color = nodeColor) } else if (itemIcon != null) { val itemstack = ItemStack(itemIcon, 1) @@ -324,17 +321,13 @@ private class AndroidResearchButton( clearDepth(graphics) } else { - drawRect(graphics, 0f, 0f, width, height) + graphics.renderRect(0f, 0f, width, height, color = nodeColor) } if (isBlockedByHovered) { - RGBAColor.RED.setSystemColor() - - Widgets18.CROSS.render(graphics) + Widgets18.CROSS.render(graphics, color = RGBAColor.RED) } else if (node.isAnyBlockerResearched) { - RGBAColor.RED.setSystemColor() - - Widgets18.FORWARD_SLASH.render(graphics) + Widgets18.FORWARD_SLASH.render(graphics, color = RGBAColor.RED) } val text = node.type.iconText @@ -343,29 +336,24 @@ private class AndroidResearchButton( graphics.drawString(font, text.visualOrderText, width - font.width(text), height - font.lineHeight, -0x1, true) } - drawColor = RGBAColor.WHITE - RGBAColor.WHITE.setShaderColor() - for (line in lines) { val (pos1, pos2) = line val (x1, y1) = pos1 val (x2, y2) = pos2 - drawLine(graphics, x1, y1, x2, y2, 0.5f) + graphics.drawLine(x1, y1, x2, y2, 0.5f, color = RGBAColor.WHITE) } hovered ?: return val pathLines = highlightLines[hovered.type] if (pathLines != null) { - drawColor = RGBAColor.LIGHT_GREEN - for (line in pathLines) { val (pos1, pos2) = line val (x1, y1) = pos1 val (x2, y2) = pos2 - drawLine(graphics, x1, y1, x2, y2, 0.5f) + graphics.drawLine(x1, y1, x2, y2, 0.5f, color = RGBAColor.LIGHT_GREEN) } } @@ -377,8 +365,6 @@ private class AndroidResearchButton( val blockLines = highlightLines[blocker] if (blockLines != null) { - drawColor = RGBAColor.RED - for (line in blockLines) { if (drawn.containsKey(line)) { continue @@ -390,7 +376,7 @@ private class AndroidResearchButton( val (x1, y1) = pos1 val (x2, y2) = pos2 - drawLine(graphics, x1, y1, x2, y2, 0.5f) + graphics.drawLine(x1, y1, x2, y2, 0.5f, color = RGBAColor.RED) } } } @@ -515,8 +501,7 @@ class AndroidStationScreen constructor(p_97741_: AndroidStationMenu, p_97742_: I private var firstTick = false override fun innerRender(graphics: GuiGraphics, mouseX: Float, mouseY: Float, partialTick: Float) { - drawColor = RGBAColor.BLACK - drawRect(graphics, 0f, 0f, width, height) + graphics.renderRect(0f, 0f, width, height, color = RGBAColor.BLACK) } override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean { diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/core/math/RGBAColor.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/core/math/RGBAColor.kt index 3b61517be..01eb2ba9c 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/core/math/RGBAColor.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/core/math/RGBAColor.kt @@ -16,66 +16,51 @@ data class RGBAColor(val red: Float, val green: Float, val blue: Float, val alph (((color and 0xFF)) / 255f) ) - fun toInt(): Int { - val r = (this.red * 255).roundToInt() - val g = (this.green * 255).roundToInt() - val b = (this.blue * 255).roundToInt() - return (r shl 16) or (g shl 8) or b + val isWhite = red >= 1f && green >= 1f && blue >= 1f && alpha >= 1f + + val redInt = (red.coerceIn(0f, 1f) * 255f).roundToInt() + val greenInt = (green.coerceIn(0f, 1f) * 255f).roundToInt() + val blueInt = (blue.coerceIn(0f, 1f) * 255f).roundToInt() + val alphaInt = (alpha.coerceIn(0f, 1f) * 255f).roundToInt() + + fun toRGB(): Int { + return (redInt shl 16) or (greenInt shl 8) or blueInt } fun toRGBA(): Int { - val r = (this.red * 255).roundToInt() - val g = (this.green * 255).roundToInt() - val b = (this.blue * 255).roundToInt() - val a = (this.alpha * 255).roundToInt() - return (r shl 24) or (g shl 16) or (b shl 8) or a + return (redInt shl 24) or (greenInt shl 16) or (blueInt shl 8) or alphaInt } fun toARGB(): Int { - val r = (this.red * 255).roundToInt() - val g = (this.green * 255).roundToInt() - val b = (this.blue * 255).roundToInt() - val a = (this.alpha * 255).roundToInt() - return (a shl 24) or (r shl 16) or (g shl 8) or b + return (alphaInt shl 24) or (redInt shl 16) or (greenInt shl 8) or blueInt } fun toBGRA(): Int { - val r = (this.red * 255).roundToInt() - val g = (this.green * 255).roundToInt() - val b = (this.blue * 255).roundToInt() - val a = (this.alpha * 255).roundToInt() - return (r shl 24) or (g shl 16) or (r shl 8) or a + return (blueInt shl 24) or (greenInt shl 16) or (redInt shl 8) or alphaInt } fun toIntInv(): Int { - val r = (this.red * 255).roundToInt() - val g = (this.green * 255).roundToInt() - val b = (this.blue * 255).roundToInt() - return (b shl 16) or (g shl 8) or r + return (blueInt shl 16) or (greenInt shl 8) or redInt } - fun setSystemColor() { - setShaderColor() - setDrawColor() - } - - fun setShaderColor() { - RenderSystem.setShaderColor(red, green, blue, alpha) - } - - fun setDrawColor() { - ru.dbotthepony.mc.otm.client.render.setDrawColor(this) - } - - fun linearInterpolation(t: Float, other: RGBAColor): RGBAColor { + fun linearInterpolation(t: Float, other: RGBAColor, interpolateAlpha: Boolean = true): RGBAColor { return RGBAColor( linearInterpolation(t, red, other.red), linearInterpolation(t, green, other.green), linearInterpolation(t, blue, other.blue), - linearInterpolation(t, alpha, other.alpha), + if (interpolateAlpha) linearInterpolation(t, alpha, other.alpha) else alpha, ) } + operator fun times(other: RGBAColor): RGBAColor { + if (isWhite) + return other + else if (other.isWhite) + return this + + return RGBAColor(red * other.red, green * other.green, blue * other.blue, alpha * other.alpha) + } + val isFullyTransparent get() = alpha <= 0f companion object { @@ -109,6 +94,9 @@ data class RGBAColor(val red: Float, val green: Float, val blue: Float, val alph @JvmField val LOW_PATTERNS = RGBAColor(44, 104, 57) @JvmField val FULL_PATTERNS = RGBAColor(65, 255, 87) + @JvmField val HALF_TRANSPARENT = RGBAColor(1f, 1f, 1f, 0.5f) + @JvmField val REDDISH = RGBAColor(1f, 0.4f, 0.4f) + fun inv(color: Int): RGBAColor { val r = (color and -0x1000000 ushr 24) / 255f val g = (color and 0xFF0000 ushr 16) / 255f diff --git a/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/AbstractWeaponItem.kt b/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/AbstractWeaponItem.kt index 19c2c5f02..1824364c8 100644 --- a/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/AbstractWeaponItem.kt +++ b/src/main/kotlin/ru/dbotthepony/mc/otm/item/weapon/AbstractWeaponItem.kt @@ -25,8 +25,7 @@ import ru.dbotthepony.mc.otm.capability.matteryEnergy import ru.dbotthepony.mc.otm.client.font import ru.dbotthepony.mc.otm.client.render.RenderGravity import ru.dbotthepony.mc.otm.client.render.drawAligned -import ru.dbotthepony.mc.otm.client.render.drawRect -import ru.dbotthepony.mc.otm.client.render.setDrawColor +import ru.dbotthepony.mc.otm.client.render.renderRect import ru.dbotthepony.mc.otm.core.* import ru.dbotthepony.mc.otm.core.math.Angle import ru.dbotthepony.mc.otm.core.math.RGBAColor @@ -459,26 +458,23 @@ abstract class AbstractWeaponItem(val tables: KClass, pr pose.rotateY(PI.toFloat()) pose.scale(0.01f, 0.01f, 0.01f) - setDrawColor(holoHudBackground) - drawRect(pose, -2f, -2f, 72f, 34f) + renderRect(pose.last().pose(), -2f, -2f, 72f, 34f, color = holoHudBackground) stack.matteryEnergy?.let { pose.pushPose() pose.translate(0.0, 0.0, -1.0) pose.scale(0.7f, 0.7f, 0.7f) val text = it.batteryLevel.formatPower() - font.drawAligned(pose, text, RenderGravity.TOP_LEFT, 2f, 2f, RGBAColor.WHITE.toInt()) + font.drawAligned(pose, text, RenderGravity.TOP_LEFT, 2f, 2f, RGBAColor.WHITE.toRGB()) pose.popPose() } pose.translate(60.0, 0.0, 0.0) - setDrawColor(heatBackground) - drawRect(pose, -1f, -1f, 9f, 32f) + renderRect(pose.last().pose(), -1f, -1f, 9f, 32f, color = heatBackground) val heat = item.heatProgress(stack, event.partialTick.toDouble()).toFloat() - setDrawColor(linearInterpolation(heat, initialHeatColor, finalHeatColor)) - drawRect(pose, 0f, 30f * (1f - heat), 7f, 30f * heat) + renderRect(pose.last().pose(), 0f, 30f * (1f - heat), 7f, 30f * heat, color = linearInterpolation(heat, initialHeatColor, finalHeatColor)) } pose.popPose()