Skip to content

Commit 895e8c8

Browse files
committed
重构着色器部分, 完善文档
1 parent 4240f1a commit 895e8c8

33 files changed

Lines changed: 2483 additions & 956 deletions

common/src/main/java/cn/coostack/cooparticlesapi/mixin/GameRendererMixin.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package cn.coostack.cooparticlesapi.mixin;
22

3-
import cn.coostack.cooparticlesapi.renderer.client.ClientRenderEntityManager;
3+
import cn.coostack.cooparticlesapi.renderer.client.ClientRenderPipelineManager;
44
import net.minecraft.client.DeltaTracker;
55
import net.minecraft.client.renderer.GameRenderer;
66
import org.spongepowered.asm.mixin.Mixin;
@@ -19,6 +19,6 @@ public class GameRendererMixin {
1919
)
2020
)
2121
private void renderAfterWorld(DeltaTracker deltaTracker, CallbackInfo ci) {
22-
ClientRenderEntityManager.INSTANCE.flushFrameComposites();
22+
ClientRenderPipelineManager.INSTANCE.endFrame();
2323
}
2424
}

common/src/main/java/cn/coostack/cooparticlesapi/mixin/LevelRendererMixin.java

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package cn.coostack.cooparticlesapi.mixin;
22

33
import cn.coostack.cooparticlesapi.CooParticlesAPIClient;
4-
import cn.coostack.cooparticlesapi.renderer.client.ClientRenderEntityManager;
4+
import cn.coostack.cooparticlesapi.renderer.client.ClientRenderPipelineManager;
55
import net.minecraft.client.Camera;
66
import net.minecraft.client.DeltaTracker;
77
import net.minecraft.client.multiplayer.ClientLevel;
@@ -39,13 +39,10 @@ public void renderBeforeEntity(DeltaTracker deltaTracker,
3939
return;
4040
}
4141
CooParticlesAPIClient.initShaderPrograms();
42+
CooParticlesAPIClient.syncRenderBackend();
4243
boolean shouldTick = level.tickRateManager().runsNormally();
4344
float tickDelta = deltaTracker.getGameTimeDeltaPartialTick(!shouldTick);
44-
ClientRenderEntityManager.INSTANCE.cacheFrameState(tickDelta, frustumMatrix, projectionMatrix);
45-
if (CooParticlesAPIClient.checkIrisShaderPackUsed()) {
46-
return;
47-
}
48-
ClientRenderEntityManager.INSTANCE.renderWorldPass(tickDelta, frustumMatrix, projectionMatrix);
45+
ClientRenderPipelineManager.INSTANCE.beginFrame(tickDelta, frustumMatrix, projectionMatrix);
4946
}
5047

5148
@Inject(method = "renderLevel", at = @At("RETURN"))
@@ -62,12 +59,9 @@ public void renderOnTail(DeltaTracker deltaTracker,
6259
return;
6360
}
6461
CooParticlesAPIClient.initShaderPrograms();
62+
CooParticlesAPIClient.syncRenderBackend();
6563
boolean shouldTick = level.tickRateManager().runsNormally();
6664
float tickDelta = deltaTracker.getGameTimeDeltaPartialTick(!shouldTick);
67-
ClientRenderEntityManager.INSTANCE.cacheFrameState(tickDelta, frustumMatrix, projectionMatrix);
68-
if (CooParticlesAPIClient.checkIrisShaderPackUsed()) {
69-
ClientRenderEntityManager.INSTANCE.renderWorldPass(tickDelta, frustumMatrix, projectionMatrix);
70-
}
71-
ClientRenderEntityManager.INSTANCE.preparePostProcess(tickDelta, frustumMatrix, projectionMatrix);
65+
ClientRenderPipelineManager.INSTANCE.finishLevelRender(tickDelta, frustumMatrix, projectionMatrix);
7266
}
7367
}

common/src/main/kotlin/cn/coostack/cooparticlesapi/CooParticlesAPI.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import cn.coostack.cooparticlesapi.network.particle.emitters.event.ParticleEvent
1414
import cn.coostack.cooparticlesapi.network.particle.style.ParticleStyleManager
1515
import cn.coostack.cooparticlesapi.platform.CooParticlesServices
1616
import cn.coostack.cooparticlesapi.renderer.server.ServerRenderEntityManager
17+
import cn.coostack.cooparticlesapi.renderer.runtime.RenderEntityAutoRegistry
1718
import cn.coostack.cooparticlesapi.scheduler.CooScheduler
1819
import cn.coostack.cooparticlesapi.test.APITestGroupBuilder
1920
import cn.coostack.cooparticlesapi.test.TestManager
@@ -59,6 +60,7 @@ object CooParticlesAPI {
5960
ParticleEmittersManager.registerScanner()
6061
DisplayEntityManager.registerScanner()
6162
ParticleCompositionManager.registerScanner()
63+
RenderEntityAutoRegistry.registerScanner()
6264
}
6365

6466
fun onServerStart(server: MinecraftServer) {
@@ -98,4 +100,4 @@ object CooParticlesAPI {
98100
ParticleCompositionManager.tickServer()
99101
TestManager.doTickServer()
100102
}
101-
}
103+
}

common/src/main/kotlin/cn/coostack/cooparticlesapi/CooParticlesAPIClient.kt

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,9 @@ import cn.coostack.cooparticlesapi.particles.CooModParticles
99
import cn.coostack.cooparticlesapi.particles.CooParticleTextureSheet
1010
import cn.coostack.cooparticlesapi.particles.control.group.ClientParticleGroupManager
1111
import cn.coostack.cooparticlesapi.platform.CooParticlesServices
12+
import cn.coostack.cooparticlesapi.renderer.backend.IrisSafeRenderBackend
13+
import cn.coostack.cooparticlesapi.renderer.backend.RenderBackend
14+
import cn.coostack.cooparticlesapi.renderer.backend.VanillaSafeRenderBackend
1215
import cn.coostack.cooparticlesapi.renderer.client.ClientRenderEntityManager
1316
import cn.coostack.cooparticlesapi.renderer.client.ClientPersistentBloomManager
1417
import cn.coostack.cooparticlesapi.renderer.client.ClientRenderPipelineManager
@@ -23,8 +26,6 @@ import cn.coostack.cooparticlesapi.test.options.particle.client.ScaleCircleGroup
2326
import cn.coostack.cooparticlesapi.test.options.particle.client.SequencedMagicCircleClient
2427
import cn.coostack.cooparticlesapi.test.options.particle.client.TestGroupClient
2528
import cn.coostack.cooparticlesapi.test.options.particle.style.*
26-
import cn.coostack.cooparticlesapi.test.options.renderer.TestRendererEntity
27-
import cn.coostack.cooparticlesapi.test.options.renderer.TestShaderInit
2829
import cn.coostack.cooparticlesapi.utils.ClientCameraUtil
2930
import net.irisshaders.iris.api.v0.IrisApi
3031
import net.minecraft.client.multiplayer.ClientLevel
@@ -37,6 +38,7 @@ object CooParticlesAPIClient {
3738

3839
@JvmField
3940
var irisLoaded = false
41+
private var selectedRenderBackend: RenderBackend = VanillaSafeRenderBackend
4042
lateinit var access: RegistryAccess
4143

4244
@JvmStatic
@@ -53,6 +55,17 @@ object CooParticlesAPIClient {
5355
return irisLoaded && IrisApi.getInstance().isShaderPackInUse
5456
}
5557

58+
@JvmStatic
59+
fun syncRenderBackend(): RenderBackend {
60+
selectedRenderBackend = if (checkIrisShaderPackUsed()) {
61+
IrisSafeRenderBackend
62+
} else {
63+
VanillaSafeRenderBackend
64+
}
65+
ClientRenderPipelineManager.setActiveBackend(selectedRenderBackend)
66+
return selectedRenderBackend
67+
}
68+
5669
private fun initParticleType() {
5770
ParticleEmittersManager.init()
5871
CooModParticles.reg()
@@ -122,6 +135,7 @@ object CooParticlesAPIClient {
122135
renderInit = true
123136
ShaderPipeManagers.init() // 注册到pipeline
124137
ClientRenderPipelineManager.init() // 把注册的pipeline进行一个初始化
138+
ClientRenderPipelineManager.setActiveBackend(selectedRenderBackend)
125139
ClientRenderEntityManager.init()
126140
CooParticlesConstants.logger.info("初始化渲染管线")
127141
}
@@ -138,9 +152,6 @@ object CooParticlesAPIClient {
138152
ClientWorldLightManager.initOnClient()
139153
ClientPersistentBloomManager.initOnClient()
140154
ClientScreenGlowManager.initOnClient()
141-
ClientRenderEntityManager.register(TestRendererEntity.id, TestRendererEntity.codec)
142-
ClientRenderEntityManager.bindEntityRenderPipe(TestRendererEntity.id, ShaderPipeManagers.simpleBloom.pipeID)
143-
TestShaderInit.initOnClient()
144155
CooParticleTextureSheet.init()
145156
}
146157

common/src/main/kotlin/cn/coostack/cooparticlesapi/CooShaderReloadSupport.kt

Lines changed: 1 addition & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,12 @@
11
package cn.coostack.cooparticlesapi
22

33
import cn.coostack.cooparticlesapi.test.options.display.MCShaders
4-
import cn.coostack.cooparticlesapi.test.options.renderer.TestAccretionDiskEntity
5-
import cn.coostack.cooparticlesapi.test.options.renderer.TestBillboardSmokeEntity
6-
import cn.coostack.cooparticlesapi.test.options.renderer.TestBlackHoleEntity
7-
import cn.coostack.cooparticlesapi.test.options.renderer.TestGlowSphereEntity
8-
import cn.coostack.cooparticlesapi.test.options.renderer.TestHybridGlowPipeEntity
9-
import cn.coostack.cooparticlesapi.test.options.renderer.TestPersistentGlowSphereEntity
10-
import cn.coostack.cooparticlesapi.test.options.renderer.TestRendererEntity
11-
import cn.coostack.cooparticlesapi.test.options.renderer.TestTexturedBeamEntity
124
import net.minecraft.server.packs.resources.ResourceManager
135

146
object CooShaderReloadSupport {
157
@JvmStatic
168
fun reload(resourceManager: ResourceManager) {
17-
TestRendererEntity.reloadStaticResources()
18-
TestTexturedBeamEntity.reloadStaticResources()
19-
TestHybridGlowPipeEntity.reloadStaticResources()
20-
TestBillboardSmokeEntity.reloadStaticResources()
21-
TestGlowSphereEntity.reloadStaticResources()
22-
TestPersistentGlowSphereEntity.reloadStaticResources()
23-
TestBlackHoleEntity.reloadStaticResources()
24-
TestAccretionDiskEntity.reloadStaticResources()
9+
// Legacy V1 renderer demo reload hooks are disabled during the V2 migration.
2510
MCShaders.init(resourceManager)
2611
CooParticlesAPIClient.reloadShaderPrograms()
2712
}

common/src/main/kotlin/cn/coostack/cooparticlesapi/annotations/codec/CodecHelper.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ import net.minecraft.world.phys.AABB
4242
import net.minecraft.world.phys.Vec3
4343
import org.joml.Quaternionf
4444
import org.joml.Vector3f
45+
import org.joml.Vector4f
4546
import java.lang.reflect.Modifier
4647
import java.util.UUID
4748
import java.util.concurrent.ConcurrentHashMap
@@ -66,6 +67,14 @@ object CodecHelper {
6667
register(CompositionEmittersData::class.java, CompositionEmittersData.PACKET_CODEC)
6768
register(DisplayEntityEmittersData::class.java, DisplayEntityEmittersData.PACKET_CODEC)
6869
register(Vector3f::class.java, StreamCodec.of({ buf, i -> buf.writeVector3f(i) }, { it.readVector3f() }))
70+
register(Vector4f::class.java, StreamCodec.of({ buf, v ->
71+
buf.writeFloat(v.x)
72+
buf.writeFloat(v.y)
73+
buf.writeFloat(v.z)
74+
buf.writeFloat(v.w)
75+
}, {
76+
Vector4f(it.readFloat(), it.readFloat(), it.readFloat(), it.readFloat())
77+
}))
6978
register(Vec3::class.java, StreamCodec.of({ buf, i -> buf.writeVec3(i) }, { it.readVec3() }))
7079
register(Quaternionf::class.java, StreamCodec.of({ buf, q -> buf.writeQuaternion(q) }, { it.readQuaternion() }))
7180
register(AABB::class.java, StreamCodec.of({ buf, i ->
@@ -334,7 +343,9 @@ object CodecHelper {
334343
if (current::class.java != other::class.java) return
335344
val fields = current::class.java.declaredFields
336345
fields.filter {
337-
it.isAnnotationPresent(CodecField::class.java) && !Modifier.isFinal(it.modifiers)
346+
it.isAnnotationPresent(CodecField::class.java) &&
347+
!Modifier.isFinal(it.modifiers) &&
348+
!Modifier.isStatic(it.modifiers)
338349
}.forEach { field ->
339350
field.isAccessible = true
340351
field.set(current, field.get(other))
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
package cn.coostack.cooparticlesapi.annotations.renderer.handle
2+
3+
import cn.coostack.cooparticlesapi.annotations.CodecField
4+
import cn.coostack.cooparticlesapi.annotations.codec.CodecHelper
5+
import cn.coostack.cooparticlesapi.renderer.RenderEntity
6+
import net.minecraft.network.FriendlyByteBuf
7+
import net.minecraft.network.codec.StreamCodec
8+
import net.minecraft.world.level.Level
9+
import net.minecraft.world.phys.Vec3
10+
import java.lang.reflect.Modifier
11+
12+
object RenderEntityHelper {
13+
/**
14+
* 生成编解码器
15+
*
16+
* 必须提供构造器 (Level?, Vec3) 或无参构造
17+
*
18+
* @param randomInstance 任意一个 RenderEntity 实例
19+
* @return 这个实例按照注解的参数的编解码器
20+
*/
21+
fun generateCodec(randomInstance: RenderEntity): StreamCodec<FriendlyByteBuf, RenderEntity> {
22+
val type = randomInstance::class.java
23+
val noArgCtor = runCatching { type.getConstructor() }.getOrNull()
24+
val levelVecCtor = runCatching { type.getConstructor(Level::class.java, Vec3::class.java) }.getOrNull()
25+
val factory = when {
26+
noArgCtor != null -> {
27+
{ noArgCtor.newInstance() as RenderEntity }
28+
}
29+
levelVecCtor != null -> {
30+
{ levelVecCtor.newInstance(null, Vec3.ZERO) as RenderEntity }
31+
}
32+
else -> {
33+
throw IllegalStateException(
34+
"RenderEntity requires public no-arg or (Level, Vec3) constructor: ${type.name}"
35+
)
36+
}
37+
}
38+
39+
return StreamCodec.of(
40+
{ buf, entity ->
41+
RenderEntity.encodeBase(buf, entity)
42+
val fields = type.declaredFields.filter {
43+
it.isAnnotationPresent(CodecField::class.java) &&
44+
!Modifier.isFinal(it.modifiers) &&
45+
!Modifier.isStatic(it.modifiers)
46+
}.sortedBy { it.name }
47+
48+
fields.forEach { field ->
49+
field.isAccessible = true
50+
val codecKey = field.type
51+
val codec: StreamCodec<FriendlyByteBuf, Any> =
52+
CodecHelper.supposedTypes[codecKey.name] as? StreamCodec<FriendlyByteBuf, Any>
53+
?: throw IllegalArgumentException(
54+
"存在不支持的类型 :${codecKey.name} 需要使用CodecHelper.register()进行注册类型"
55+
)
56+
codec.encode(buf, field.get(entity))
57+
}
58+
},
59+
{ buf ->
60+
factory().apply {
61+
RenderEntity.decodeBase(buf, this)
62+
val fields = type.declaredFields.filter {
63+
it.isAnnotationPresent(CodecField::class.java) &&
64+
!Modifier.isFinal(it.modifiers) &&
65+
!Modifier.isStatic(it.modifiers)
66+
}.sortedBy { it.name }
67+
68+
fields.forEach { field ->
69+
field.isAccessible = true
70+
val codecKey = field.type
71+
val codec: StreamCodec<FriendlyByteBuf, Any> =
72+
CodecHelper.supposedTypes[codecKey.name] as? StreamCodec<FriendlyByteBuf, Any>
73+
?: throw IllegalArgumentException(
74+
"存在不支持的类型 :${codecKey.name} 需要使用CodecHelper.register()进行注册类型"
75+
)
76+
val value = codec.decode(buf)
77+
field.set(this, value)
78+
}
79+
}
80+
}
81+
)
82+
}
83+
}

common/src/main/kotlin/cn/coostack/cooparticlesapi/exceptions/RenderPipeNotFoundException.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,5 @@ package cn.coostack.cooparticlesapi.exceptions
33
import net.minecraft.resources.ResourceLocation
44

55
class RenderPipeNotFoundException(var renderID: ResourceLocation) :
6-
Exception("Render $renderID's bound pipe manager not fount, you need to use ClientRenderEntityManager.bindEntityRenderPipe(YourRenderEntity.ID, YourRegisteredPipeManager.pipeID to bind a output pipe manager") {
7-
}
6+
Exception("Render $renderID's bound pipe manager not found. Register a renderer/codec through the V2 registry and ensure the runtime config provides a pipe manager.") {
7+
}

common/src/main/kotlin/cn/coostack/cooparticlesapi/items/TestTickItem.kt

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
package cn.coostack.cooparticlesapi.items
22

33
import cn.coostack.cooparticlesapi.event.CooEventBus
4-
import cn.coostack.cooparticlesapi.renderer.server.ServerRenderEntityManager
54
import cn.coostack.cooparticlesapi.test.options.event.TestChildEvent
65
import cn.coostack.cooparticlesapi.test.options.event.TestEvent
7-
import cn.coostack.cooparticlesapi.test.options.renderer.TestRendererEntity
86
import net.minecraft.network.chat.Component
97
import net.minecraft.server.level.ServerLevel
108
import net.minecraft.server.level.ServerPlayer
@@ -24,16 +22,14 @@ class TestTickItem : Item(Item.Properties().stacksTo(1)) {
2422
)
2523

2624
if (world.isClientSide) return super.use(world, user, hand)
27-
// testShader(world as ServerLevel, user as ServerPlayer)
25+
// Legacy V1 renderer demo spawn is disabled during the RenderEntity V2 migration.
2826

2927
return super.use(world, user, hand)
3028
}
3129

32-
fun testShader(world: ServerLevel, user: ServerPlayer) {
33-
val shader = TestRendererEntity(world)
34-
shader.setPosition(user.position())
35-
ServerRenderEntityManager.spawn(shader)
36-
}
30+
// fun testShader(world: ServerLevel, user: ServerPlayer) {
31+
// Legacy V1 renderer demo spawn is disabled during the RenderEntity V2 migration.
32+
// }
3733

3834
fun tickFrozen(world: ServerLevel, user: ServerPlayer) {
3935
val server = world.server!!
@@ -57,4 +53,4 @@ class TestTickItem : Item(Item.Properties().stacksTo(1)) {
5753
)
5854
}
5955

60-
}
56+
}

common/src/main/kotlin/cn/coostack/cooparticlesapi/network/packet/client/listener/ClientRenderEntityPacketHandler.kt

Lines changed: 26 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,10 @@ package cn.coostack.cooparticlesapi.network.packet.client.listener
33
import cn.coostack.cooparticlesapi.network.packet.server.PacketRenderEntityS2C
44
import cn.coostack.cooparticlesapi.platform.network.ClientContext
55
import cn.coostack.cooparticlesapi.renderer.client.ClientRenderEntityManager
6+
import cn.coostack.cooparticlesapi.renderer.runtime.ClientRenderEntityRegistry
7+
import cn.coostack.cooparticlesapi.renderer.runtime.RenderEntityInstance
8+
import cn.coostack.cooparticlesapi.renderer.runtime.RenderEntityRenderer
9+
import cn.coostack.cooparticlesapi.renderer.RenderEntity
610
import io.netty.buffer.Unpooled
711
import net.minecraft.network.FriendlyByteBuf
812

@@ -15,21 +19,37 @@ object ClientRenderEntityPacketHandler {
1519
val data = packet.entityData
1620
val id = packet.id
1721
val buf = FriendlyByteBuf(Unpooled.wrappedBuffer(data))
18-
val codec = ClientRenderEntityManager.getCodecFromID(id) ?: return
19-
val entity = codec.decode(buf)
22+
val type = ClientRenderEntityRegistry.get(id) ?: return
23+
val entity = type.codec.decode(buf)
2024
entity.world = context.client().level
2125
when (method) {
2226
PacketRenderEntityS2C.Method.CREATE -> {
23-
ClientRenderEntityManager.add(entity)
27+
val renderer = resolveRenderer(entity, type, id)
28+
val instance = RenderEntityInstance(entity, renderer)
29+
ClientRenderEntityManager.add(instance)
2430
}
2531

2632
PacketRenderEntityS2C.Method.TOGGLE -> {
27-
ClientRenderEntityManager.getFrom(packet.uuid)?.loadProfileFromEntity(entity)
33+
ClientRenderEntityManager.getFrom(packet.uuid)?.updateFrom(entity)
2834
}
2935

3036
PacketRenderEntityS2C.Method.REMOVE -> {
31-
ClientRenderEntityManager.getFrom(packet.uuid)?.canceled = true
37+
ClientRenderEntityManager.getFrom(packet.uuid)?.markRemoved()
3238
}
3339
}
3440
}
35-
}
41+
42+
@Suppress("UNCHECKED_CAST")
43+
private fun resolveRenderer(
44+
entity: RenderEntity,
45+
type: cn.coostack.cooparticlesapi.renderer.runtime.ClientRenderEntityType,
46+
id: net.minecraft.resources.ResourceLocation
47+
): RenderEntityRenderer<RenderEntity> {
48+
if (entity is RenderEntityRenderer<*>) {
49+
return entity as RenderEntityRenderer<RenderEntity>
50+
}
51+
val factory = type.rendererFactory
52+
?: throw IllegalStateException("RenderEntity renderer not registered: $id")
53+
return factory.invoke() as RenderEntityRenderer<RenderEntity>
54+
}
55+
}

0 commit comments

Comments
 (0)