Atlas skin element rendertypes, buffer upload things

This commit is contained in:
DBotThePony 2022-10-07 12:59:51 +07:00
parent 13d2506661
commit b8923ba31d
Signed by: DBot
GPG Key ID: DCC23B5715498507
4 changed files with 178 additions and 9 deletions

View File

@ -14,8 +14,10 @@ import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonWriter
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.PoseStack
import com.mojang.blaze3d.vertex.VertexConsumer
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import ru.dbotthepony.mc.otm.core.RGBAColor
import ru.dbotthepony.mc.otm.core.linearInterpolation
import java.lang.reflect.Type
@ -201,6 +203,93 @@ sealed class AbstractSkinElement {
winding: UVWindingOrder = this.winding
) = renderRawPartial(stack, x.toFloat(), y.toFloat(), width.toFloat(), height.toFloat(), winding)
protected fun uploadOnto(
pose: PoseStack,
builder: VertexConsumer,
x: Float,
y: Float,
width: Float,
height: Float,
z: Float,
color: RGBAColor?,
u0: Float,
v0: Float,
u1: Float,
v1: Float,
) {
val intColor = color?.toRGBA() ?: 0
val matrix = pose.last().pose()
builder.vertex(matrix, x, y + height, z).uv(u0, v1).also { if (color != null) it.color(intColor) }.endVertex()
builder.vertex(matrix, x + width, y + height, z).uv(u1, v1).also { if (color != null) it.color(intColor) }.endVertex()
builder.vertex(matrix, x + width, y, z).uv(u1, v0).also { if (color != null) it.color(intColor) }.endVertex()
builder.vertex(matrix, x, y, z).uv(u0, v0).also { if (color != null) it.color(intColor) }.endVertex()
}
@JvmOverloads
fun uploadOnto(
pose: PoseStack,
builder: VertexConsumer,
x: Float = 0f,
y: Float = 0f,
width: Float = this.width,
height: Float = this.height,
z: Float = 0f,
color: RGBAColor? = null,
winding: UVWindingOrder = this.winding,
) {
val (u0, v0, u1, v1) = winding.translate(u0, v0, u1, v1)
uploadOnto(pose, builder, x, y, width, height, z, color, u0, v0, u1, v1)
}
@JvmOverloads
fun uploadOntoPartial(
pose: PoseStack,
builder: VertexConsumer,
x: Float = 0f,
y: Float = 0f,
width: Float = this.width,
height: Float = this.height,
z: Float = 0f,
color: RGBAColor? = null,
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 (u0_, v0_, u1_, v1_) = winding.translate(u0, v0, u1, v1)
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? = null,
winding: UVWindingOrder = this.winding,
) {
uploadOnto(pose, builder, x, y, width, height, z, color, winding)
}
abstract fun toJson(): JsonElement
abstract fun toNetwork(buff: FriendlyByteBuf)

View File

@ -10,10 +10,19 @@ import com.google.gson.TypeAdapter
import com.google.gson.internal.bind.TypeAdapters
import com.google.gson.stream.JsonReader
import com.google.gson.stream.JsonWriter
import com.mojang.blaze3d.systems.RenderSystem
import com.mojang.blaze3d.vertex.DefaultVertexFormat
import com.mojang.blaze3d.vertex.VertexFormat
import net.minecraft.client.renderer.GameRenderer
import net.minecraft.client.renderer.RenderStateShard
import net.minecraft.client.renderer.RenderStateShard.TextureStateShard
import net.minecraft.client.renderer.RenderType
import net.minecraft.client.renderer.texture.TextureAtlasSprite
import net.minecraft.network.FriendlyByteBuf
import net.minecraft.resources.ResourceLocation
import org.lwjgl.opengl.GL11.GL_ALWAYS
import ru.dbotthepony.mc.otm.isClient
import ru.dbotthepony.mc.otm.isClientThread
import java.lang.reflect.Type
import java.util.stream.Stream
@ -30,7 +39,7 @@ class AtlasSkinElement private constructor(
check(isClient) { "Invalid realm" }
val _textureAtlasSprite = _textureAtlasSprite
if (_textureAtlasSprite == null || changeset != WidgetAtlasHolder.INSTANCE.changeset || WidgetAtlasHolder.INSTANCE.demandsRebuild) {
if (_textureAtlasSprite == null || changeset != WidgetAtlasHolder.INSTANCE.changeset || (WidgetAtlasHolder.INSTANCE.demandsRebuild && isClientThread())) {
val get = WidgetAtlasHolder.INSTANCE.getSprite(location)
this._textureAtlasSprite = get
changeset = WidgetAtlasHolder.INSTANCE.changeset
@ -54,7 +63,7 @@ class AtlasSkinElement private constructor(
override val v0 get() = textureAtlasSprite.v0
override val u1 get() = textureAtlasSprite.u1
override val v1 get() = textureAtlasSprite.v1
override val texture: ResourceLocation get() = textureAtlasSprite.atlas().location()
override val texture: ResourceLocation get() = WidgetAtlasHolder.LOCATION
override fun equals(other: Any?): Boolean {
if (other is AtlasSkinElement)
@ -143,5 +152,50 @@ class AtlasSkinElement private constructor(
): AtlasSkinElement {
return fromJson(json)
}
val renderTypeGUI by lazy {
val builder = RenderType.CompositeState.builder()
builder.setTextureState(TextureStateShard(WidgetAtlasHolder.LOCATION, false, false))
builder.setShaderState(RenderStateShard.ShaderStateShard(GameRenderer::getPositionColorTexShader))
builder.setDepthTestState(RenderStateShard.DepthTestStateShard("always", GL_ALWAYS))
builder.setTransparencyState(RenderStateShard.TransparencyStateShard("normal_blend", {
RenderSystem.enableBlend()
RenderSystem.defaultBlendFunc()
}, {
RenderSystem.disableBlend()
}))
@Suppress("INACCESSIBLE_TYPE")
RenderType.create("gui_element",
DefaultVertexFormat.POSITION_COLOR_TEX,
VertexFormat.Mode.QUADS,
2048,
false,
false,
builder.createCompositeState(false)) as RenderType
}
val renderTypeWorld by lazy {
val builder = RenderType.CompositeState.builder()
builder.setTextureState(TextureStateShard(WidgetAtlasHolder.LOCATION, false, false))
builder.setShaderState(RenderStateShard.ShaderStateShard(GameRenderer::getPositionColorTexShader))
builder.setTransparencyState(RenderStateShard.TransparencyStateShard("normal_blend", {
RenderSystem.enableBlend()
RenderSystem.defaultBlendFunc()
}, {
RenderSystem.disableBlend()
}))
@Suppress("INACCESSIBLE_TYPE")
RenderType.create("gui_element_world",
DefaultVertexFormat.POSITION_COLOR_TEX,
VertexFormat.Mode.QUADS,
2048,
false,
false,
builder.createCompositeState(false)) as RenderType
}
}
}

View File

@ -12,6 +12,7 @@ import ru.dbotthepony.mc.otm.OverdriveThatMatters
import ru.dbotthepony.mc.otm.client.LOGGED_IN
import ru.dbotthepony.mc.otm.client.minecraft
import ru.dbotthepony.mc.otm.client.onceClient
import ru.dbotthepony.mc.otm.isClientThread
import ru.dbotthepony.mc.otm.registry.WriteOnce
import java.util.stream.Stream
import kotlin.properties.Delegates
@ -45,7 +46,7 @@ class WidgetAtlasHolder private constructor(manager: TextureManager) : TextureAt
throw IllegalStateException("Trying to get sprite too early")
}
if (demandsRebuild) {
if (demandsRebuild && isClientThread()) {
apply(prepare(resourceManager, profileManager), resourceManager, profileManager)
}

View File

@ -2,6 +2,7 @@ package ru.dbotthepony.mc.otm.core
import com.mojang.blaze3d.systems.RenderSystem
import net.minecraft.ChatFormatting
import kotlin.math.roundToInt
data class RGBAColor(val red: Float, val green: Float, val blue: Float, val alpha: Float = 1f) {
constructor(r: Int, g: Int, b: Int) : this((r / 255f), (g / 255f), (b / 255f), 1f)
@ -16,16 +17,40 @@ data class RGBAColor(val red: Float, val green: Float, val blue: Float, val alph
)
fun toInt(): Int {
val r = (this.red * 255).toInt()
val g = (this.green * 255).toInt()
val b = (this.blue * 255).toInt()
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
}
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
}
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
}
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
}
fun toIntInv(): Int {
val r = (this.red * 255).toInt()
val g = (this.green * 255).toInt()
val b = (this.blue * 255).toInt()
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
}