LevelRenderer.java
net.minecraft.client.renderer.LevelRenderer
信息
- 全限定名:net.minecraft.client.renderer.LevelRenderer
- 类型:public class
- 包:net.minecraft.client.renderer
- 源码路径:src/main/java/net/minecraft/client/renderer/LevelRenderer.java
- 起始行号:L127
- 实现:ResourceManagerReloadListener, AutoCloseable
- 职责:
TODO
字段/常量
-
TRANSPARENCY_POST_CHAIN_ID- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L128 - 说明:
TODO
- 类型:
-
ENTITY_OUTLINE_POST_CHAIN_ID- 类型:
Identifier - 修饰符:
private static final - 源码定位:
L129 - 说明:
TODO
- 类型:
-
SECTION_SIZE- 类型:
int - 修饰符:
public static final - 源码定位:
L130 - 说明:
TODO
- 类型:
-
HALF_SECTION_SIZE- 类型:
int - 修饰符:
public static final - 源码定位:
L131 - 说明:
TODO
- 类型:
-
NEARBY_SECTION_DISTANCE_IN_BLOCKS- 类型:
int - 修饰符:
public static final - 源码定位:
L132 - 说明:
TODO
- 类型:
-
MINIMUM_TRANSPARENT_SORT_COUNT- 类型:
int - 修饰符:
private static final - 源码定位:
L133 - 说明:
TODO
- 类型:
-
CHUNK_VISIBILITY_THRESHOLD- 类型:
float - 修饰符:
private static final - 源码定位:
L134 - 说明:
TODO
- 类型:
-
minecraft- 类型:
Minecraft - 修饰符:
private final - 源码定位:
L135 - 说明:
TODO
- 类型:
-
entityRenderDispatcher- 类型:
EntityRenderDispatcher - 修饰符:
private final - 源码定位:
L136 - 说明:
TODO
- 类型:
-
blockEntityRenderDispatcher- 类型:
BlockEntityRenderDispatcher - 修饰符:
private final - 源码定位:
L137 - 说明:
TODO
- 类型:
-
renderBuffers- 类型:
RenderBuffers - 修饰符:
private final - 源码定位:
L138 - 说明:
TODO
- 类型:
-
skyRenderer- 类型:
SkyRenderer - 修饰符:
private - 源码定位:
L139 - 说明:
TODO
- 类型:
-
cloudRenderer- 类型:
CloudRenderer - 修饰符:
private final - 源码定位:
L140 - 说明:
TODO
- 类型:
-
worldBorderRenderer- 类型:
WorldBorderRenderer - 修饰符:
private final - 源码定位:
L141 - 说明:
TODO
- 类型:
-
weatherEffectRenderer- 类型:
WeatherEffectRenderer - 修饰符:
private final - 源码定位:
L142 - 说明:
TODO
- 类型:
-
debugRenderer- 类型:
DebugRenderer - 修饰符:
public final - 源码定位:
L143 - 说明:
TODO
- 类型:
-
gameTestBlockHighlightRenderer- 类型:
GameTestBlockHighlightRenderer - 修饰符:
public final - 源码定位:
L144 - 说明:
TODO
- 类型:
-
level- 类型:
ClientLevel - 修饰符:
private - 源码定位:
L145 - 说明:
TODO
- 类型:
-
sectionOcclusionGraph- 类型:
SectionOcclusionGraph - 修饰符:
private final - 源码定位:
L146 - 说明:
TODO
- 类型:
-
visibleSections- 类型:
ObjectArrayList<SectionRenderDispatcher.RenderSection> - 修饰符:
private final - 源码定位:
L147 - 说明:
TODO
- 类型:
-
nearbyVisibleSections- 类型:
ObjectArrayList<SectionRenderDispatcher.RenderSection> - 修饰符:
private final - 源码定位:
L148 - 说明:
TODO
- 类型:
-
viewArea- 类型:
ViewArea - 修饰符:
private - 源码定位:
L149 - 说明:
TODO
- 类型:
-
ticks- 类型:
int - 修饰符:
private - 源码定位:
L150 - 说明:
TODO
- 类型:
-
destroyingBlocks- 类型:
Int2ObjectMap<BlockDestructionProgress> - 修饰符:
private final - 源码定位:
L151 - 说明:
TODO
- 类型:
-
destructionProgress- 类型:
Long2ObjectMap<SortedSet<BlockDestructionProgress>> - 修饰符:
private final - 源码定位:
L152 - 说明:
TODO
- 类型:
-
entityOutlineTarget- 类型:
RenderTarget - 修饰符:
private - 源码定位:
L153 - 说明:
TODO
- 类型:
-
targets- 类型:
LevelTargetBundle - 修饰符:
private final - 源码定位:
L154 - 说明:
TODO
- 类型:
-
lastCameraSectionX- 类型:
int - 修饰符:
private - 源码定位:
L155 - 说明:
TODO
- 类型:
-
lastCameraSectionY- 类型:
int - 修饰符:
private - 源码定位:
L156 - 说明:
TODO
- 类型:
-
lastCameraSectionZ- 类型:
int - 修饰符:
private - 源码定位:
L157 - 说明:
TODO
- 类型:
-
prevCamX- 类型:
double - 修饰符:
private - 源码定位:
L158 - 说明:
TODO
- 类型:
-
prevCamY- 类型:
double - 修饰符:
private - 源码定位:
L159 - 说明:
TODO
- 类型:
-
prevCamZ- 类型:
double - 修饰符:
private - 源码定位:
L160 - 说明:
TODO
- 类型:
-
prevCamRotX- 类型:
double - 修饰符:
private - 源码定位:
L161 - 说明:
TODO
- 类型:
-
prevCamRotY- 类型:
double - 修饰符:
private - 源码定位:
L162 - 说明:
TODO
- 类型:
-
lastSmartCull- 类型:
boolean - 修饰符:
private - 源码定位:
L163 - 说明:
TODO
- 类型:
-
sectionRenderDispatcher- 类型:
SectionRenderDispatcher - 修饰符:
private - 源码定位:
L164 - 说明:
TODO
- 类型:
-
lastViewDistance- 类型:
int - 修饰符:
private - 源码定位:
L165 - 说明:
TODO
- 类型:
-
lastTranslucentSortBlockPos- 类型:
BlockPos - 修饰符:
private - 源码定位:
L166 - 说明:
TODO
- 类型:
-
translucencyResortIterationIndex- 类型:
int - 修饰符:
private - 源码定位:
L167 - 说明:
TODO
- 类型:
-
optionsRenderState- 类型:
OptionsRenderState - 修饰符:
private final - 源码定位:
L168 - 说明:
TODO
- 类型:
-
levelRenderState- 类型:
LevelRenderState - 修饰符:
private final - 源码定位:
L169 - 说明:
TODO
- 类型:
-
submitNodeStorage- 类型:
SubmitNodeStorage - 修饰符:
private final - 源码定位:
L170 - 说明:
TODO
- 类型:
-
featureRenderDispatcher- 类型:
FeatureRenderDispatcher - 修饰符:
private final - 源码定位:
L171 - 说明:
TODO
- 类型:
-
chunkLayerSampler- 类型:
GpuSampler - 修饰符:
private - 源码定位:
L172 - 说明:
TODO
- 类型:
-
collectedGizmos- 类型:
SimpleGizmoCollector - 修饰符:
private final - 源码定位:
L173 - 说明:
TODO
- 类型:
-
finalizedGizmos- 类型:
LevelRenderer.FinalizedGizmos - 修饰符:
private - 源码定位:
L174 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.client.renderer.LevelRenderer.BrightnessGetter- 类型:
interface - 修饰符:
public - 源码定位:
L1515 - 说明:
TODO
- 类型:
-
net.minecraft.client.renderer.LevelRenderer.FinalizedGizmos- 类型:
record - 修饰符:
private - 源码定位:
L1526 - 说明:
TODO
- 类型:
构造器
public LevelRenderer(Minecraft minecraft, EntityRenderDispatcher entityRenderDispatcher, BlockEntityRenderDispatcher blockEntityRenderDispatcher, RenderBuffers renderBuffers, GameRenderState gameRenderState, FeatureRenderDispatcher featureRenderDispatcher) @ L176
- 构造器名:LevelRenderer
- 源码定位:L176
- 修饰符:public
参数:
- minecraft: Minecraft
- entityRenderDispatcher: EntityRenderDispatcher
- blockEntityRenderDispatcher: BlockEntityRenderDispatcher
- renderBuffers: RenderBuffers
- gameRenderState: GameRenderState
- featureRenderDispatcher: FeatureRenderDispatcher
说明:
TODO
方法
下面的方法块按源码顺序生成。
public void close() @ L194
- 方法名:close
- 源码定位:L194
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void onResourceManagerReload(ResourceManager resourceManager) @ L211
- 方法名:onResourceManagerReload
- 源码定位:L211
- 返回类型:void
- 修饰符:public
参数:
- resourceManager: ResourceManager
说明:
TODO
public void initOutline() @ L221
- 方法名:initOutline
- 源码定位:L221
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
private PostChain getTransparencyChain() @ L230
- 方法名:getTransparencyChain
- 源码定位:L230
- 返回类型:PostChain
- 修饰符:private
参数:
- 无
说明:
TODO
public void doEntityOutline() @ L236
- 方法名:doEntityOutline
- 源码定位:L236
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
protected boolean shouldShowEntityOutlines() @ L242
- 方法名:shouldShowEntityOutlines
- 源码定位:L242
- 返回类型:boolean
- 修饰符:protected
参数:
- 无
说明:
TODO
public void setLevel(ClientLevel level) @ L246
- 方法名:setLevel
- 源码定位:L246
- 返回类型:void
- 修饰符:public
参数:
- level: ClientLevel
说明:
TODO
private void clearVisibleSections() @ L272
- 方法名:clearVisibleSections
- 源码定位:L272
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
public void allChanged() @ L277
- 方法名:allChanged
- 源码定位:L277
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void resize(int width, int height) @ L314
- 方法名:resize
- 源码定位:L314
- 返回类型:void
- 修饰符:public
参数:
- width: int
- height: int
说明:
TODO
public String getSectionStatistics() @ L321
- 方法名:getSectionStatistics
- 源码定位:L321
- 返回类型:String
- 修饰符:public
参数:
- 无
说明:
TODO
public SectionRenderDispatcher getSectionRenderDispatcher() @ L339
- 方法名:getSectionRenderDispatcher
- 源码定位:L339
- 返回类型:SectionRenderDispatcher
- 修饰符:public
参数:
- 无
说明:
TODO
public double getTotalSections() @ L343
- 方法名:getTotalSections
- 源码定位:L343
- 返回类型:double
- 修饰符:public
参数:
- 无
说明:
TODO
public double getLastViewDistance() @ L347
- 方法名:getLastViewDistance
- 源码定位:L347
- 返回类型:double
- 修饰符:public
参数:
- 无
说明:
TODO
public int countRenderedSections() @ L351
- 方法名:countRenderedSections
- 源码定位:L351
- 返回类型:int
- 修饰符:public
参数:
- 无
说明:
TODO
public void resetSampler() @ L363
- 方法名:resetSampler
- 源码定位:L363
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public String getEntityStatistics() @ L371
- 方法名:getEntityStatistics
- 源码定位:L371
- 返回类型:String
- 修饰符:public
参数:
- 无
说明:
TODO
private void cullTerrain(Camera camera, Frustum frustum, boolean spectator) @ L382
- 方法名:cullTerrain
- 源码定位:L382
- 返回类型:void
- 修饰符:private
参数:
- camera: Camera
- frustum: Frustum
- spectator: boolean
说明:
TODO
public static Frustum offsetFrustum(Frustum frustum) @ L439
- 方法名:offsetFrustum
- 源码定位:L439
- 返回类型:Frustum
- 修饰符:public static
参数:
- frustum: Frustum
说明:
TODO
private void applyFrustum(Frustum frustum) @ L443
- 方法名:applyFrustum
- 源码定位:L443
- 返回类型:void
- 修饰符:private
参数:
- frustum: Frustum
说明:
TODO
public void addRecentlyCompiledSection(SectionRenderDispatcher.RenderSection section) @ L452
- 方法名:addRecentlyCompiledSection
- 源码定位:L452
- 返回类型:void
- 修饰符:public
参数:
- section: SectionRenderDispatcher.RenderSection
说明:
TODO
public void update(Camera camera) @ L456
- 方法名:update
- 源码定位:L456
- 返回类型:void
- 修饰符:public
参数:
- camera: Camera
说明:
TODO
public void renderLevel(GraphicsResourceAllocator resourceAllocator, DeltaTracker deltaTracker, boolean renderOutline, CameraRenderState cameraState, Matrix4fc modelViewMatrix, GpuBufferSlice terrainFog, Vector4f fogColor, boolean shouldRenderSky, ChunkSectionsToRender chunkSectionsToRender) @ L465
- 方法名:renderLevel
- 源码定位:L465
- 返回类型:void
- 修饰符:public
参数:
- resourceAllocator: GraphicsResourceAllocator
- deltaTracker: DeltaTracker
- renderOutline: boolean
- cameraState: CameraRenderState
- modelViewMatrix: Matrix4fc
- terrainFog: GpuBufferSlice
- fogColor: Vector4f
- shouldRenderSky: boolean
- chunkSectionsToRender: ChunkSectionsToRender
说明:
TODO
public void extractLevel(DeltaTracker deltaTracker, Camera camera, float deltaPartialTick) @ L569
- 方法名:extractLevel
- 源码定位:L569
- 返回类型:void
- 修饰符:public
参数:
- deltaTracker: DeltaTracker
- camera: Camera
- deltaPartialTick: float
说明:
TODO
private void addMainPass(FrameGraphBuilder frame, Frustum frustum, Matrix4fc modelViewMatrix, GpuBufferSlice terrainFog, boolean renderOutline, LevelRenderState levelRenderState, DeltaTracker deltaTracker, ProfilerFiller profiler, ChunkSectionsToRender chunkSectionsToRender) @ L617
- 方法名:addMainPass
- 源码定位:L617
- 返回类型:void
- 修饰符:private
参数:
- frame: FrameGraphBuilder
- frustum: Frustum
- modelViewMatrix: Matrix4fc
- terrainFog: GpuBufferSlice
- renderOutline: boolean
- levelRenderState: LevelRenderState
- deltaTracker: DeltaTracker
- profiler: ProfilerFiller
- chunkSectionsToRender: ChunkSectionsToRender
说明:
TODO
private void addCloudsPass(FrameGraphBuilder frame, CloudStatus cloudStatus, Vec3 cameraPosition, long gameTime, float partialTicks, int cloudColor, float cloudHeight, int cloudRange) @ L738
- 方法名:addCloudsPass
- 源码定位:L738
- 返回类型:void
- 修饰符:private
参数:
- frame: FrameGraphBuilder
- cloudStatus: CloudStatus
- cameraPosition: Vec3
- gameTime: long
- partialTicks: float
- cloudColor: int
- cloudHeight: float
- cloudRange: int
说明:
TODO
private void addWeatherPass(FrameGraphBuilder frame, GpuBufferSlice fog) @ L758
- 方法名:addWeatherPass
- 源码定位:L758
- 返回类型:void
- 修饰符:private
参数:
- frame: FrameGraphBuilder
- fog: GpuBufferSlice
说明:
TODO
private void addLateDebugPass(FrameGraphBuilder frame, CameraRenderState camera, GpuBufferSlice fog, Matrix4fc modelViewMatrix) @ L778
- 方法名:addLateDebugPass
- 源码定位:L778
- 返回类型:void
- 修饰符:private
参数:
- frame: FrameGraphBuilder
- camera: CameraRenderState
- fog: GpuBufferSlice
- modelViewMatrix: Matrix4fc
说明:
TODO
private void extractVisibleEntities(Camera camera, Frustum frustum, DeltaTracker deltaTracker, LevelRenderState output) @ L805
- 方法名:extractVisibleEntities
- 源码定位:L805
- 返回类型:void
- 修饰符:private
参数:
- camera: Camera
- frustum: Frustum
- deltaTracker: DeltaTracker
- output: LevelRenderState
说明:
TODO
private void submitEntities(PoseStack poseStack, LevelRenderState levelRenderState, SubmitNodeCollector output) @ L845
- 方法名:submitEntities
- 源码定位:L845
- 返回类型:void
- 修饰符:private
参数:
- poseStack: PoseStack
- levelRenderState: LevelRenderState
- output: SubmitNodeCollector
说明:
TODO
private void extractVisibleBlockEntities(Camera camera, float deltaPartialTick, LevelRenderState levelRenderState) @ L860
- 方法名:extractVisibleBlockEntities
- 源码定位:L860
- 返回类型:void
- 修饰符:private
参数:
- camera: Camera
- deltaPartialTick: float
- levelRenderState: LevelRenderState
说明:
TODO
private void submitBlockEntities(PoseStack poseStack, LevelRenderState levelRenderState, SubmitNodeStorage submitNodeStorage) @ L906
- 方法名:submitBlockEntities
- 源码定位:L906
- 返回类型:void
- 修饰符:private
参数:
- poseStack: PoseStack
- levelRenderState: LevelRenderState
- submitNodeStorage: SubmitNodeStorage
说明:
TODO
private void extractBlockDestroyAnimation(Camera camera, LevelRenderState levelRenderState) @ L921
- 方法名:extractBlockDestroyAnimation
- 源码定位:L921
- 返回类型:void
- 修饰符:private
参数:
- camera: Camera
- levelRenderState: LevelRenderState
说明:
TODO
private void submitBlockDestroyAnimation(PoseStack poseStack, SubmitNodeCollector submitNodeCollector, LevelRenderState levelRenderState) @ L940
- 方法名:submitBlockDestroyAnimation
- 源码定位:L940
- 返回类型:void
- 修饰符:private
参数:
- poseStack: PoseStack
- submitNodeCollector: SubmitNodeCollector
- levelRenderState: LevelRenderState
说明:
TODO
private void extractBlockOutline(Camera camera, LevelRenderState levelRenderState) @ L958
- 方法名:extractBlockOutline
- 源码定位:L958
- 返回类型:void
- 修饰符:private
参数:
- camera: Camera
- levelRenderState: LevelRenderState
说明:
TODO
private void renderBlockOutline(MultiBufferSource.BufferSource bufferSource, PoseStack poseStack, boolean onlyTranslucentBlocks, LevelRenderState levelRenderState) @ L985
- 方法名:renderBlockOutline
- 源码定位:L985
- 返回类型:void
- 修饰符:private
参数:
- bufferSource: MultiBufferSource.BufferSource
- poseStack: PoseStack
- onlyTranslucentBlocks: boolean
- levelRenderState: LevelRenderState
说明:
TODO
private void checkPoseStack(PoseStack poseStack) @ L1014
- 方法名:checkPoseStack
- 源码定位:L1014
- 返回类型:void
- 修饰符:private
参数:
- poseStack: PoseStack
说明:
TODO
private EntityRenderState extractEntity(Entity entity, float partialTickTime) @ L1020
- 方法名:extractEntity
- 源码定位:L1020
- 返回类型:EntityRenderState
- 修饰符:private
参数:
- entity: Entity
- partialTickTime: float
说明:
TODO
private void scheduleTranslucentSectionResort(Vec3 cameraPos) @ L1024
- 方法名:scheduleTranslucentSectionResort
- 源码定位:L1024
- 返回类型:void
- 修饰符:private
参数:
- cameraPos: Vec3
说明:
TODO
private void scheduleResort(SectionRenderDispatcher.RenderSection section, TranslucencyPointOfView pointOfView, Vec3 cameraPos, boolean blockPosChanged, boolean isNearby) @ L1046
- 方法名:scheduleResort
- 源码定位:L1046
- 返回类型:void
- 修饰符:private
参数:
- section: SectionRenderDispatcher.RenderSection
- pointOfView: TranslucencyPointOfView
- cameraPos: Vec3
- blockPosChanged: boolean
- isNearby: boolean
说明:
TODO
public ChunkSectionsToRender prepareChunkRenders(Matrix4fc modelViewMatrix) @ L1057
- 方法名:prepareChunkRenders
- 源码定位:L1057
- 返回类型:ChunkSectionsToRender
- 修饰符:public
参数:
- modelViewMatrix: Matrix4fc
说明:
TODO
public void endFrame() @ L1160
- 方法名:endFrame
- 源码定位:L1160
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public void tick(Camera camera) @ L1164
- 方法名:tick
- 源码定位:L1164
- 返回类型:void
- 修饰符:public
参数:
- camera: Camera
说明:
TODO
private void removeBlockBreakingProgress() @ L1174
- 方法名:removeBlockBreakingProgress
- 源码定位:L1174
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
private void removeProgress(BlockDestructionProgress block) @ L1189
- 方法名:removeProgress
- 源码定位:L1189
- 返回类型:void
- 修饰符:private
参数:
- block: BlockDestructionProgress
说明:
TODO
private void addSkyPass(FrameGraphBuilder frame, CameraRenderState cameraState, GpuBufferSlice skyFog) @ L1198
- 方法名:addSkyPass
- 源码定位:L1198
- 返回类型:void
- 修饰符:private
参数:
- frame: FrameGraphBuilder
- cameraState: CameraRenderState
- skyFog: GpuBufferSlice
说明:
TODO
private void compileSections(Camera camera) @ L1234
- 方法名:compileSections
- 源码定位:L1234
- 返回类型:void
- 修饰符:private
参数:
- camera: Camera
说明:
TODO
private void renderHitOutline(PoseStack poseStack, VertexConsumer builder, double camX, double camY, double camZ, BlockOutlineRenderState state, int color, float width) @ L1284
- 方法名:renderHitOutline
- 源码定位:L1284
- 返回类型:void
- 修饰符:private
参数:
- poseStack: PoseStack
- builder: VertexConsumer
- camX: double
- camY: double
- camZ: double
- state: BlockOutlineRenderState
- color: int
- width: float
说明:
TODO
public void blockChanged(BlockGetter level, BlockPos pos, BlockState old, BlockState current, int updateFlags) @ L1335
- 方法名:blockChanged
- 源码定位:L1335
- 返回类型:void
- 修饰符:public
参数:
- level: BlockGetter
- pos: BlockPos
- old: BlockState
- current: BlockState
- updateFlags: int
说明:
TODO
private void setBlockDirty(BlockPos pos, boolean playerChanged) @ L1339
- 方法名:setBlockDirty
- 源码定位:L1339
- 返回类型:void
- 修饰符:private
参数:
- pos: BlockPos
- playerChanged: boolean
说明:
TODO
public void setBlocksDirty(int x0, int y0, int z0, int x1, int y1, int z1) @ L1349
- 方法名:setBlocksDirty
- 源码定位:L1349
- 返回类型:void
- 修饰符:public
参数:
- x0: int
- y0: int
- z0: int
- x1: int
- y1: int
- z1: int
说明:
TODO
public void setBlockDirty(BlockPos pos, BlockState oldState, BlockState newState) @ L1359
- 方法名:setBlockDirty
- 源码定位:L1359
- 返回类型:void
- 修饰符:public
参数:
- pos: BlockPos
- oldState: BlockState
- newState: BlockState
说明:
TODO
public void setSectionDirtyWithNeighbors(int sectionX, int sectionY, int sectionZ) @ L1365
- 方法名:setSectionDirtyWithNeighbors
- 源码定位:L1365
- 返回类型:void
- 修饰符:public
参数:
- sectionX: int
- sectionY: int
- sectionZ: int
说明:
TODO
public void setSectionRangeDirty(int minSectionX, int minSectionY, int minSectionZ, int maxSectionX, int maxSectionY, int maxSectionZ) @ L1369
- 方法名:setSectionRangeDirty
- 源码定位:L1369
- 返回类型:void
- 修饰符:public
参数:
- minSectionX: int
- minSectionY: int
- minSectionZ: int
- maxSectionX: int
- maxSectionY: int
- maxSectionZ: int
说明:
TODO
public void setSectionDirty(int sectionX, int sectionY, int sectionZ) @ L1379
- 方法名:setSectionDirty
- 源码定位:L1379
- 返回类型:void
- 修饰符:public
参数:
- sectionX: int
- sectionY: int
- sectionZ: int
说明:
TODO
private void setSectionDirty(int sectionX, int sectionY, int sectionZ, boolean playerChanged) @ L1383
- 方法名:setSectionDirty
- 源码定位:L1383
- 返回类型:void
- 修饰符:private
参数:
- sectionX: int
- sectionY: int
- sectionZ: int
- playerChanged: boolean
说明:
TODO
public void onSectionBecomingNonEmpty(long sectionNode) @ L1387
- 方法名:onSectionBecomingNonEmpty
- 源码定位:L1387
- 返回类型:void
- 修饰符:public
参数:
- sectionNode: long
说明:
TODO
public void destroyBlockProgress(int id, BlockPos pos, int progress) @ L1395
- 方法名:destroyBlockProgress
- 源码定位:L1395
- 返回类型:void
- 修饰符:public
参数:
- id: int
- pos: BlockPos
- progress: int
说明:
TODO
public boolean hasRenderedAllSections() @ L1418
- 方法名:hasRenderedAllSections
- 源码定位:L1418
- 返回类型:boolean
- 修饰符:public
参数:
- 无
说明:
TODO
public void onChunkReadyToRender(ChunkPos pos) @ L1422
- 方法名:onChunkReadyToRender
- 源码定位:L1422
- 返回类型:void
- 修饰符:public
参数:
- pos: ChunkPos
说明:
TODO
public void needsUpdate() @ L1426
- 方法名:needsUpdate
- 源码定位:L1426
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public static int getLightCoords(BlockAndLightGetter level, BlockPos pos) @ L1431
- 方法名:getLightCoords
- 源码定位:L1431
- 返回类型:int
- 修饰符:public static
参数:
- level: BlockAndLightGetter
- pos: BlockPos
说明:
TODO
public static int getLightCoords(LevelRenderer.BrightnessGetter brightnessGetter, BlockAndLightGetter level, BlockState state, BlockPos pos) @ L1435
- 方法名:getLightCoords
- 源码定位:L1435
- 返回类型:int
- 修饰符:public static
参数:
- brightnessGetter: LevelRenderer.BrightnessGetter
- level: BlockAndLightGetter
- state: BlockState
- pos: BlockPos
说明:
TODO
public boolean isSectionCompiledAndVisible(BlockPos blockPos) @ L1446
- 方法名:isSectionCompiledAndVisible
- 源码定位:L1446
- 返回类型:boolean
- 修饰符:public
参数:
- blockPos: BlockPos
说明:
TODO
public RenderTarget entityOutlineTarget() @ L1453
- 方法名:entityOutlineTarget
- 源码定位:L1453
- 返回类型:RenderTarget
- 修饰符:public
参数:
- 无
说明:
TODO
public RenderTarget getTranslucentTarget() @ L1457
- 方法名:getTranslucentTarget
- 源码定位:L1457
- 返回类型:RenderTarget
- 修饰符:public
参数:
- 无
说明:
TODO
public RenderTarget getItemEntityTarget() @ L1461
- 方法名:getItemEntityTarget
- 源码定位:L1461
- 返回类型:RenderTarget
- 修饰符:public
参数:
- 无
说明:
TODO
public RenderTarget getParticlesTarget() @ L1465
- 方法名:getParticlesTarget
- 源码定位:L1465
- 返回类型:RenderTarget
- 修饰符:public
参数:
- 无
说明:
TODO
public RenderTarget getWeatherTarget() @ L1469
- 方法名:getWeatherTarget
- 源码定位:L1469
- 返回类型:RenderTarget
- 修饰符:public
参数:
- 无
说明:
TODO
public RenderTarget getCloudsTarget() @ L1473
- 方法名:getCloudsTarget
- 源码定位:L1473
- 返回类型:RenderTarget
- 修饰符:public
参数:
- 无
说明:
TODO
public ObjectArrayList<SectionRenderDispatcher.RenderSection> getVisibleSections() @ L1477
- 方法名:getVisibleSections
- 源码定位:L1477
- 返回类型:ObjectArrayList<SectionRenderDispatcher.RenderSection>
- 修饰符:public
参数:
- 无
说明:
TODO
public SectionOcclusionGraph getSectionOcclusionGraph() @ L1482
- 方法名:getSectionOcclusionGraph
- 源码定位:L1482
- 返回类型:SectionOcclusionGraph
- 修饰符:public
参数:
- 无
说明:
TODO
public CloudRenderer getCloudRenderer() @ L1487
- 方法名:getCloudRenderer
- 源码定位:L1487
- 返回类型:CloudRenderer
- 修饰符:public
参数:
- 无
说明:
TODO
public Gizmos.TemporaryCollection collectPerFrameGizmos() @ L1491
- 方法名:collectPerFrameGizmos
- 源码定位:L1491
- 返回类型:Gizmos.TemporaryCollection
- 修饰符:public
参数:
- 无
说明:
TODO
private void finalizeGizmoCollection() @ L1495
- 方法名:finalizeGizmoCollection
- 源码定位:L1495
- 返回类型:void
- 修饰符:private
参数:
- 无
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class LevelRenderer implements ResourceManagerReloadListener, AutoCloseable {
private static final Identifier TRANSPARENCY_POST_CHAIN_ID = Identifier.withDefaultNamespace("transparency");
private static final Identifier ENTITY_OUTLINE_POST_CHAIN_ID = Identifier.withDefaultNamespace("entity_outline");
public static final int SECTION_SIZE = 16;
public static final int HALF_SECTION_SIZE = 8;
public static final int NEARBY_SECTION_DISTANCE_IN_BLOCKS = 32;
private static final int MINIMUM_TRANSPARENT_SORT_COUNT = 15;
private static final float CHUNK_VISIBILITY_THRESHOLD = 0.3F;
private final Minecraft minecraft;
private final EntityRenderDispatcher entityRenderDispatcher;
private final BlockEntityRenderDispatcher blockEntityRenderDispatcher;
private final RenderBuffers renderBuffers;
private @Nullable SkyRenderer skyRenderer;
private final CloudRenderer cloudRenderer = new CloudRenderer();
private final WorldBorderRenderer worldBorderRenderer = new WorldBorderRenderer();
private final WeatherEffectRenderer weatherEffectRenderer = new WeatherEffectRenderer();
public final DebugRenderer debugRenderer = new DebugRenderer();
public final GameTestBlockHighlightRenderer gameTestBlockHighlightRenderer = new GameTestBlockHighlightRenderer();
private @Nullable ClientLevel level;
private final SectionOcclusionGraph sectionOcclusionGraph = new SectionOcclusionGraph();
private final ObjectArrayList<SectionRenderDispatcher.RenderSection> visibleSections = new ObjectArrayList<>(10000);
private final ObjectArrayList<SectionRenderDispatcher.RenderSection> nearbyVisibleSections = new ObjectArrayList<>(50);
private @Nullable ViewArea viewArea;
private int ticks;
private final Int2ObjectMap<BlockDestructionProgress> destroyingBlocks = new Int2ObjectOpenHashMap<>();
private final Long2ObjectMap<SortedSet<BlockDestructionProgress>> destructionProgress = new Long2ObjectOpenHashMap<>();
private @Nullable RenderTarget entityOutlineTarget;
private final LevelTargetBundle targets = new LevelTargetBundle();
private int lastCameraSectionX = Integer.MIN_VALUE;
private int lastCameraSectionY = Integer.MIN_VALUE;
private int lastCameraSectionZ = Integer.MIN_VALUE;
private double prevCamX = Double.MIN_VALUE;
private double prevCamY = Double.MIN_VALUE;
private double prevCamZ = Double.MIN_VALUE;
private double prevCamRotX = Double.MIN_VALUE;
private double prevCamRotY = Double.MIN_VALUE;
private boolean lastSmartCull = true;
private @Nullable SectionRenderDispatcher sectionRenderDispatcher;
private int lastViewDistance = -1;
private @Nullable BlockPos lastTranslucentSortBlockPos;
private int translucencyResortIterationIndex;
private final OptionsRenderState optionsRenderState;
private final LevelRenderState levelRenderState;
private final SubmitNodeStorage submitNodeStorage;
private final FeatureRenderDispatcher featureRenderDispatcher;
private @Nullable GpuSampler chunkLayerSampler;
private final SimpleGizmoCollector collectedGizmos = new SimpleGizmoCollector();
private LevelRenderer.FinalizedGizmos finalizedGizmos = new LevelRenderer.FinalizedGizmos(new DrawableGizmoPrimitives(), new DrawableGizmoPrimitives());
public LevelRenderer(
Minecraft minecraft,
EntityRenderDispatcher entityRenderDispatcher,
BlockEntityRenderDispatcher blockEntityRenderDispatcher,
RenderBuffers renderBuffers,
GameRenderState gameRenderState,
FeatureRenderDispatcher featureRenderDispatcher
) {
this.minecraft = minecraft;
this.entityRenderDispatcher = entityRenderDispatcher;
this.blockEntityRenderDispatcher = blockEntityRenderDispatcher;
this.renderBuffers = renderBuffers;
this.submitNodeStorage = featureRenderDispatcher.getSubmitNodeStorage();
this.optionsRenderState = gameRenderState.optionsRenderState;
this.levelRenderState = gameRenderState.levelRenderState;
this.featureRenderDispatcher = featureRenderDispatcher;
}
@Override
public void close() {
if (this.entityOutlineTarget != null) {
this.entityOutlineTarget.destroyBuffers();
}
if (this.skyRenderer != null) {
this.skyRenderer.close();
}
if (this.chunkLayerSampler != null) {
this.chunkLayerSampler.close();
}
this.cloudRenderer.close();
}
@Override
public void onResourceManagerReload(ResourceManager resourceManager) {
this.initOutline();
if (this.skyRenderer != null) {
this.skyRenderer.close();
}
this.skyRenderer = new SkyRenderer(this.minecraft.getTextureManager(), this.minecraft.getAtlasManager());
}
public void initOutline() {
if (this.entityOutlineTarget != null) {
this.entityOutlineTarget.destroyBuffers();
}
WindowRenderState windowState = this.minecraft.gameRenderer.getGameRenderState().windowRenderState;
this.entityOutlineTarget = new TextureTarget("Entity Outline", windowState.width, windowState.height, true);
}
private @Nullable PostChain getTransparencyChain() {
return !Minecraft.useShaderTransparency()
? null
: this.minecraft.getShaderManager().getPostChain(TRANSPARENCY_POST_CHAIN_ID, LevelTargetBundle.SORTING_TARGETS);
}
public void doEntityOutline() {
if (this.shouldShowEntityOutlines()) {
this.entityOutlineTarget.blitAndBlendToTexture(this.minecraft.getMainRenderTarget().getColorTextureView());
}
}
protected boolean shouldShowEntityOutlines() {
return !this.levelRenderState.cameraRenderState.isPanoramicMode && this.entityOutlineTarget != null && this.minecraft.player != null;
}
public void setLevel(@Nullable ClientLevel level) {
this.lastCameraSectionX = Integer.MIN_VALUE;
this.lastCameraSectionY = Integer.MIN_VALUE;
this.lastCameraSectionZ = Integer.MIN_VALUE;
this.level = level;
if (level != null) {
this.allChanged();
} else {
this.entityRenderDispatcher.resetCamera();
if (this.viewArea != null) {
this.viewArea.releaseAllBuffers();
this.viewArea = null;
}
if (this.sectionRenderDispatcher != null) {
this.sectionRenderDispatcher.dispose();
}
this.sectionRenderDispatcher = null;
this.sectionOcclusionGraph.waitAndReset(null);
this.clearVisibleSections();
}
this.gameTestBlockHighlightRenderer.clear();
}
private void clearVisibleSections() {
this.visibleSections.clear();
this.nearbyVisibleSections.clear();
}
public void allChanged() {
if (this.level != null) {
this.level.clearTintCaches();
Options options = this.minecraft.options;
boolean ambientOcclusion = options.ambientOcclusion().get();
boolean cutoutLeaves = options.cutoutLeaves().get();
ModelManager modelManager = this.minecraft.getModelManager();
SectionCompiler sectionCompiler = new SectionCompiler(
ambientOcclusion,
cutoutLeaves,
modelManager.getBlockStateModelSet(),
modelManager.getFluidStateModelSet(),
this.minecraft.getBlockColors(),
this.minecraft.getBlockEntityRenderDispatcher()
);
if (this.sectionRenderDispatcher == null) {
this.sectionRenderDispatcher = new SectionRenderDispatcher(this.level, this, Util.backgroundExecutor(), this.renderBuffers, sectionCompiler);
} else {
this.sectionRenderDispatcher.setLevel(this.level, sectionCompiler);
}
this.cloudRenderer.markForRebuild();
LeavesBlock.setCutoutLeaves(cutoutLeaves);
this.lastViewDistance = options.getEffectiveRenderDistance();
if (this.viewArea != null) {
this.viewArea.releaseAllBuffers();
}
this.sectionRenderDispatcher.clearCompileQueue();
this.viewArea = new ViewArea(this.sectionRenderDispatcher, this.level, options.getEffectiveRenderDistance(), this);
this.sectionOcclusionGraph.waitAndReset(this.viewArea);
this.clearVisibleSections();
Camera camera = this.minecraft.gameRenderer.getMainCamera();
this.viewArea.repositionCamera(SectionPos.of(camera.position()));
}
}
public void resize(int width, int height) {
this.needsUpdate();
if (this.entityOutlineTarget != null) {
this.entityOutlineTarget.resize(width, height);
}
}
public @Nullable String getSectionStatistics() {
if (this.viewArea == null) {
return null;
} else {
int totalSections = this.viewArea.sections.length;
int rendered = this.countRenderedSections();
return String.format(
Locale.ROOT,
"C: %d/%d %sD: %d, %s",
rendered,
totalSections,
this.minecraft.smartCull ? "(s) " : "",
this.lastViewDistance,
this.sectionRenderDispatcher == null ? "null" : this.sectionRenderDispatcher.getStats()
);
}
}
public @Nullable SectionRenderDispatcher getSectionRenderDispatcher() {
return this.sectionRenderDispatcher;
}
public double getTotalSections() {
return this.viewArea == null ? 0.0 : this.viewArea.sections.length;
}
public double getLastViewDistance() {
return this.lastViewDistance;
}
public int countRenderedSections() {
int rendered = 0;
for (SectionRenderDispatcher.RenderSection section : this.visibleSections) {
if (section.getSectionMesh().hasRenderableLayers()) {
rendered++;
}
}
return rendered;
}
public void resetSampler() {
if (this.chunkLayerSampler != null) {
this.chunkLayerSampler.close();
}
this.chunkLayerSampler = null;
}
public @Nullable String getEntityStatistics() {
return this.level == null
? null
: "E: "
+ this.levelRenderState.lastEntityRenderStateCount
+ "/"
+ this.level.getEntityCount()
+ ", SD: "
+ this.level.getServerSimulationDistance();
}
private void cullTerrain(Camera camera, Frustum frustum, boolean spectator) {
Vec3 cameraPos = camera.position();
if (this.minecraft.options.getEffectiveRenderDistance() != this.lastViewDistance) {
this.allChanged();
}
ProfilerFiller profiler = Profiler.get();
profiler.push("repositionCamera");
int cameraSectionX = SectionPos.posToSectionCoord(cameraPos.x());
int cameraSectionY = SectionPos.posToSectionCoord(cameraPos.y());
int cameraSectionZ = SectionPos.posToSectionCoord(cameraPos.z());
if (this.lastCameraSectionX != cameraSectionX || this.lastCameraSectionY != cameraSectionY || this.lastCameraSectionZ != cameraSectionZ) {
this.lastCameraSectionX = cameraSectionX;
this.lastCameraSectionY = cameraSectionY;
this.lastCameraSectionZ = cameraSectionZ;
this.viewArea.repositionCamera(SectionPos.of(cameraPos));
this.worldBorderRenderer.invalidate();
}
this.sectionRenderDispatcher.setCameraPosition(cameraPos);
double camX = Math.floor(cameraPos.x / 8.0);
double camY = Math.floor(cameraPos.y / 8.0);
double camZ = Math.floor(cameraPos.z / 8.0);
if (camX != this.prevCamX || camY != this.prevCamY || camZ != this.prevCamZ) {
this.sectionOcclusionGraph.invalidate();
}
this.prevCamX = camX;
this.prevCamY = camY;
this.prevCamZ = camZ;
profiler.pop();
if (camera.getCapturedFrustum() == null) {
boolean smartCull = this.minecraft.smartCull;
if (spectator && this.level.getBlockState(camera.blockPosition()).isSolidRender()) {
smartCull = false;
}
if (smartCull != this.lastSmartCull) {
this.sectionOcclusionGraph.invalidate();
}
this.lastSmartCull = smartCull;
profiler.push("updateSOG");
this.sectionOcclusionGraph.update(smartCull, camera, frustum, this.visibleSections, this.level.getChunkSource().getLoadedEmptySections());
profiler.pop();
double camRotX = Math.floor(camera.xRot() / 2.0F);
double camRotY = Math.floor(camera.yRot() / 2.0F);
if (this.sectionOcclusionGraph.consumeFrustumUpdate() || camRotX != this.prevCamRotX || camRotY != this.prevCamRotY) {
profiler.push("applyFrustum");
this.applyFrustum(offsetFrustum(frustum));
profiler.pop();
this.prevCamRotX = camRotX;
this.prevCamRotY = camRotY;
}
}
}
public static Frustum offsetFrustum(Frustum frustum) {
return new Frustum(frustum).offsetToFullyIncludeCameraCube(8);
}
private void applyFrustum(Frustum frustum) {
if (!Minecraft.getInstance().isSameThread()) {
throw new IllegalStateException("applyFrustum called from wrong thread: " + Thread.currentThread().getName());
} else {
this.clearVisibleSections();
this.sectionOcclusionGraph.addSectionsInFrustum(frustum, this.visibleSections, this.nearbyVisibleSections);
}
}
public void addRecentlyCompiledSection(SectionRenderDispatcher.RenderSection section) {
this.sectionOcclusionGraph.schedulePropagationFrom(section);
}
public void update(Camera camera) {
ProfilerFiller profiler = Profiler.get();
profiler.push("cullTerrain");
this.cullTerrain(camera, camera.getCullFrustum(), this.minecraft.player.isSpectator());
profiler.popPush("compileSections");
this.compileSections(camera);
profiler.pop();
}
public void renderLevel(
GraphicsResourceAllocator resourceAllocator,
DeltaTracker deltaTracker,
boolean renderOutline,
CameraRenderState cameraState,
Matrix4fc modelViewMatrix,
GpuBufferSlice terrainFog,
Vector4f fogColor,
boolean shouldRenderSky,
ChunkSectionsToRender chunkSectionsToRender
) {
float deltaPartialTick = deltaTracker.getGameTimeDeltaPartialTick(false);
this.levelRenderState.gameTime = this.level.getGameTime();
final ProfilerFiller profiler = Profiler.get();
Frustum cullFrustum = cameraState.cullFrustum;
profiler.push("setupFrameGraph");
Matrix4fStack modelViewStack = RenderSystem.getModelViewStack();
modelViewStack.pushMatrix();
modelViewStack.mul(modelViewMatrix);
FrameGraphBuilder frame = new FrameGraphBuilder();
this.targets.main = frame.importExternal("main", this.minecraft.getMainRenderTarget());
int screenWidth = this.minecraft.getMainRenderTarget().width;
int screenHeight = this.minecraft.getMainRenderTarget().height;
RenderTargetDescriptor screenSizeTargetDescriptor = new RenderTargetDescriptor(screenWidth, screenHeight, true, 0);
PostChain transparencyChain = this.getTransparencyChain();
if (transparencyChain != null) {
this.targets.translucent = frame.createInternal("translucent", screenSizeTargetDescriptor);
this.targets.itemEntity = frame.createInternal("item_entity", screenSizeTargetDescriptor);
this.targets.particles = frame.createInternal("particles", screenSizeTargetDescriptor);
this.targets.weather = frame.createInternal("weather", screenSizeTargetDescriptor);
this.targets.clouds = frame.createInternal("clouds", screenSizeTargetDescriptor);
}
if (this.entityOutlineTarget != null) {
this.targets.entityOutline = frame.importExternal("entity_outline", this.entityOutlineTarget);
}
FramePass clearPass = frame.addPass("clear");
this.targets.main = clearPass.readsAndWrites(this.targets.main);
clearPass.executes(
() -> {
RenderTarget mainRenderTarget = this.minecraft.getMainRenderTarget();
RenderSystem.getDevice()
.createCommandEncoder()
.clearColorAndDepthTextures(
mainRenderTarget.getColorTexture(),
ARGB.colorFromFloat(0.0F, fogColor.x, fogColor.y, fogColor.z),
mainRenderTarget.getDepthTexture(),
1.0
);
}
);
if (shouldRenderSky) {
this.addSkyPass(frame, cameraState, terrainFog);
}
this.addMainPass(frame, cullFrustum, modelViewMatrix, terrainFog, renderOutline, this.levelRenderState, deltaTracker, profiler, chunkSectionsToRender);
PostChain entityOutlineChain = this.minecraft.getShaderManager().getPostChain(ENTITY_OUTLINE_POST_CHAIN_ID, LevelTargetBundle.OUTLINE_TARGETS);
if (this.levelRenderState.haveGlowingEntities && entityOutlineChain != null) {
entityOutlineChain.addToFrame(frame, screenWidth, screenHeight, this.targets);
}
CloudStatus cloudStatus = this.optionsRenderState.cloudStatus;
if (cloudStatus != CloudStatus.OFF && ARGB.alpha(this.levelRenderState.cloudColor) > 0) {
this.addCloudsPass(
frame,
cloudStatus,
this.levelRenderState.cameraRenderState.pos,
this.levelRenderState.gameTime,
deltaPartialTick,
this.levelRenderState.cloudColor,
this.levelRenderState.cloudHeight,
this.optionsRenderState.cloudRange
);
}
this.addWeatherPass(frame, terrainFog);
if (transparencyChain != null) {
transparencyChain.addToFrame(frame, screenWidth, screenHeight, this.targets);
}
this.addLateDebugPass(frame, this.levelRenderState.cameraRenderState, terrainFog, modelViewMatrix);
profiler.popPush("executeFrameGraph");
frame.execute(resourceAllocator, new FrameGraphBuilder.Inspector() {
{
Objects.requireNonNull(LevelRenderer.this);
}
@Override
public void beforeExecutePass(String name) {
profiler.push(name);
}
@Override
public void afterExecutePass(String name) {
profiler.pop();
}
});
profiler.pop();
this.targets.clear();
modelViewStack.popMatrix();
this.levelRenderState.reset();
}
public void extractLevel(DeltaTracker deltaTracker, Camera camera, float deltaPartialTick) {
ProfilerFiller profiler = Profiler.get();
profiler.push("level");
Vec3 cameraPos = camera.position();
Frustum cullFrustum = camera.getCullFrustum();
profiler.push("prepareDispatchers");
this.blockEntityRenderDispatcher.prepare(cameraPos);
this.entityRenderDispatcher.prepare(camera, this.minecraft.crosshairPickEntity);
profiler.popPush("prepareChunkDraws");
Matrix4f modelViewMatrix = new Matrix4f();
camera.getViewRotationMatrix(modelViewMatrix);
this.levelRenderState.chunkSectionsToRender = this.prepareChunkRenders(modelViewMatrix);
profiler.popPush("entities");
this.extractVisibleEntities(camera, cullFrustum, deltaTracker, this.levelRenderState);
profiler.popPush("blockEntities");
this.extractVisibleBlockEntities(camera, deltaPartialTick, this.levelRenderState);
profiler.popPush("blockOutline");
this.extractBlockOutline(camera, this.levelRenderState);
profiler.popPush("blockBreaking");
this.extractBlockDestroyAnimation(camera, this.levelRenderState);
profiler.popPush("weather");
this.weatherEffectRenderer.extractRenderState(this.level, this.ticks, deltaPartialTick, cameraPos, this.levelRenderState.weatherRenderState);
profiler.popPush("sky");
this.skyRenderer.extractRenderState(this.level, deltaPartialTick, camera, this.levelRenderState.skyRenderState);
profiler.popPush("border");
this.worldBorderRenderer
.extract(
this.level.getWorldBorder(),
deltaPartialTick,
cameraPos,
this.minecraft.options.getEffectiveRenderDistance() * 16,
this.levelRenderState.worldBorderRenderState
);
profiler.popPush("particles");
this.minecraft.particleEngine.extract(this.levelRenderState.particlesRenderState, new Frustum(cullFrustum).offset(-3.0F), camera, deltaPartialTick);
profiler.popPush("cloud");
this.levelRenderState.cloudColor = camera.attributeProbe().getValue(EnvironmentAttributes.CLOUD_COLOR, deltaPartialTick);
if (ARGB.alpha(this.levelRenderState.cloudColor) > 0) {
this.levelRenderState.cloudHeight = camera.attributeProbe().getValue(EnvironmentAttributes.CLOUD_HEIGHT, deltaPartialTick);
}
profiler.popPush("debug");
this.debugRenderer.emitGizmos(cullFrustum, cameraPos.x, cameraPos.y, cameraPos.z, deltaTracker.getGameTimeDeltaPartialTick(false));
this.gameTestBlockHighlightRenderer.emitGizmos();
profiler.pop();
profiler.pop();
}
private void addMainPass(
FrameGraphBuilder frame,
Frustum frustum,
Matrix4fc modelViewMatrix,
GpuBufferSlice terrainFog,
boolean renderOutline,
LevelRenderState levelRenderState,
DeltaTracker deltaTracker,
ProfilerFiller profiler,
ChunkSectionsToRender chunkSectionsToRender
) {
FramePass pass = frame.addPass("main");
this.targets.main = pass.readsAndWrites(this.targets.main);
if (this.targets.translucent != null) {
this.targets.translucent = pass.readsAndWrites(this.targets.translucent);
}
if (this.targets.itemEntity != null) {
this.targets.itemEntity = pass.readsAndWrites(this.targets.itemEntity);
}
if (this.targets.weather != null) {
this.targets.weather = pass.readsAndWrites(this.targets.weather);
}
if (this.targets.particles != null) {
this.targets.particles = pass.readsAndWrites(this.targets.particles);
}
if (levelRenderState.haveGlowingEntities && this.targets.entityOutline != null) {
this.targets.entityOutline = pass.readsAndWrites(this.targets.entityOutline);
}
ResourceHandle<RenderTarget> mainTarget = this.targets.main;
ResourceHandle<RenderTarget> translucentTarget = this.targets.translucent;
ResourceHandle<RenderTarget> itemEntityTarget = this.targets.itemEntity;
ResourceHandle<RenderTarget> entityOutlineTarget = this.targets.entityOutline;
ResourceHandle<RenderTarget> particleTarget = this.targets.particles;
pass.executes(
() -> {
RenderSystem.setShaderFog(terrainFog);
Vec3 cameraPos = levelRenderState.cameraRenderState.pos;
double camX = cameraPos.x();
double camY = cameraPos.y();
double camZ = cameraPos.z();
profiler.push("solidTerrain");
if (this.chunkLayerSampler == null) {
int maxAnisotropy = this.optionsRenderState.textureFiltering == TextureFilteringMethod.ANISOTROPIC
? this.optionsRenderState.maxAnisotropyValue
: 1;
this.chunkLayerSampler = RenderSystem.getDevice()
.createSampler(
AddressMode.CLAMP_TO_EDGE, AddressMode.CLAMP_TO_EDGE, FilterMode.LINEAR, FilterMode.LINEAR, maxAnisotropy, OptionalDouble.empty()
);
}
chunkSectionsToRender.renderGroup(ChunkSectionLayerGroup.OPAQUE, this.chunkLayerSampler);
this.minecraft.gameRenderer.getLighting().setupFor(Lighting.Entry.LEVEL);
if (this.shouldShowEntityOutlines() && entityOutlineTarget != null) {
RenderTarget outlineTarget = entityOutlineTarget.get();
RenderSystem.getDevice()
.createCommandEncoder()
.clearColorAndDepthTextures(outlineTarget.getColorTexture(), 0, outlineTarget.getDepthTexture(), 1.0);
}
PoseStack poseStack = new PoseStack();
MultiBufferSource.BufferSource bufferSource = this.renderBuffers.bufferSource();
MultiBufferSource.BufferSource crumblingBufferSource = this.renderBuffers.crumblingBufferSource();
profiler.popPush("submitFeatures");
this.submitEntities(poseStack, levelRenderState, this.submitNodeStorage);
this.submitBlockEntities(poseStack, levelRenderState, this.submitNodeStorage);
levelRenderState.particlesRenderState.submit(this.submitNodeStorage, levelRenderState.cameraRenderState);
this.submitBlockDestroyAnimation(poseStack, this.submitNodeStorage, levelRenderState);
profiler.popPush("renderSolidFeatures");
this.featureRenderDispatcher.renderSolidFeatures();
bufferSource.endBatch();
profiler.pop();
this.checkPoseStack(poseStack);
if (translucentTarget != null) {
translucentTarget.get().copyDepthFrom(mainTarget.get());
}
if (itemEntityTarget != null) {
itemEntityTarget.get().copyDepthFrom(mainTarget.get());
}
if (particleTarget != null) {
particleTarget.get().copyDepthFrom(mainTarget.get());
}
profiler.push("renderTranslucentFeatures");
this.featureRenderDispatcher.renderTranslucentFeatures();
bufferSource.endBatch();
crumblingBufferSource.endBatch();
profiler.pop();
this.renderBuffers.outlineBufferSource().endOutlineBatch();
if (renderOutline) {
this.renderBlockOutline(bufferSource, poseStack, false, levelRenderState);
bufferSource.endBatch();
}
this.finalizeGizmoCollection();
this.finalizedGizmos.standardPrimitives().render(poseStack, bufferSource, levelRenderState.cameraRenderState, modelViewMatrix);
bufferSource.endBatch();
this.checkPoseStack(poseStack);
profiler.push("translucentTerrain");
chunkSectionsToRender.renderGroup(ChunkSectionLayerGroup.TRANSLUCENT, this.chunkLayerSampler);
if (renderOutline) {
this.renderBlockOutline(bufferSource, poseStack, true, levelRenderState);
}
bufferSource.endBatch();
profiler.pop();
this.featureRenderDispatcher.renderTranslucentParticles();
bufferSource.endBatch();
this.featureRenderDispatcher.clearSubmitNodes();
levelRenderState.particlesRenderState.reset();
}
);
}
private void addCloudsPass(
FrameGraphBuilder frame,
CloudStatus cloudStatus,
Vec3 cameraPosition,
long gameTime,
float partialTicks,
int cloudColor,
float cloudHeight,
int cloudRange
) {
FramePass pass = frame.addPass("clouds");
if (this.targets.clouds != null) {
this.targets.clouds = pass.readsAndWrites(this.targets.clouds);
} else {
this.targets.main = pass.readsAndWrites(this.targets.main);
}
pass.executes(() -> this.cloudRenderer.render(cloudColor, cloudStatus, cloudHeight, cloudRange, cameraPosition, gameTime, partialTicks));
}
private void addWeatherPass(FrameGraphBuilder frame, GpuBufferSlice fog) {
int renderDistance = this.optionsRenderState.renderDistance * 16;
FramePass pass = frame.addPass("weather");
if (this.targets.weather != null) {
this.targets.weather = pass.readsAndWrites(this.targets.weather);
} else {
this.targets.main = pass.readsAndWrites(this.targets.main);
}
pass.executes(
() -> {
RenderSystem.setShaderFog(fog);
CameraRenderState cameraState = this.levelRenderState.cameraRenderState;
this.weatherEffectRenderer.render(cameraState.pos, this.levelRenderState.weatherRenderState);
this.worldBorderRenderer
.render(this.levelRenderState.worldBorderRenderState, cameraState.pos, renderDistance, this.levelRenderState.cameraRenderState.depthFar);
}
);
}
private void addLateDebugPass(FrameGraphBuilder frame, CameraRenderState camera, GpuBufferSlice fog, Matrix4fc modelViewMatrix) {
FramePass pass = frame.addPass("late_debug");
this.targets.main = pass.readsAndWrites(this.targets.main);
if (this.targets.itemEntity != null) {
this.targets.itemEntity = pass.readsAndWrites(this.targets.itemEntity);
}
ResourceHandle<RenderTarget> mainTarget = this.targets.main;
pass.executes(() -> {
RenderSystem.setShaderFog(fog);
PoseStack poseStack = new PoseStack();
MultiBufferSource.BufferSource bufferSource = this.renderBuffers.bufferSource();
RenderSystem.outputColorTextureOverride = mainTarget.get().getColorTextureView();
RenderSystem.outputDepthTextureOverride = mainTarget.get().getDepthTextureView();
if (!this.finalizedGizmos.alwaysOnTopPrimitives().isEmpty()) {
RenderTarget mainRenderTarget = Minecraft.getInstance().getMainRenderTarget();
RenderSystem.getDevice().createCommandEncoder().clearDepthTexture(mainRenderTarget.getDepthTexture(), 1.0);
this.finalizedGizmos.alwaysOnTopPrimitives().render(poseStack, bufferSource, camera, modelViewMatrix);
bufferSource.endLastBatch();
}
RenderSystem.outputColorTextureOverride = null;
RenderSystem.outputDepthTextureOverride = null;
this.checkPoseStack(poseStack);
});
}
private void extractVisibleEntities(Camera camera, Frustum frustum, DeltaTracker deltaTracker, LevelRenderState output) {
Vec3 cameraPos = camera.position();
double camX = cameraPos.x();
double camY = cameraPos.y();
double camZ = cameraPos.z();
TickRateManager tickRateManager = this.minecraft.level.tickRateManager();
boolean shouldShowEntityOutlines = this.shouldShowEntityOutlines();
Entity.setViewScale(
Mth.clamp(this.minecraft.options.getEffectiveRenderDistance() / 8.0, 1.0, 2.5) * this.minecraft.options.entityDistanceScaling().get()
);
for (Entity entity : this.level.entitiesForRendering()) {
if (this.entityRenderDispatcher.shouldRender(entity, frustum, camX, camY, camZ) || entity.hasIndirectPassenger(this.minecraft.player)) {
BlockPos blockPos = entity.blockPosition();
if ((this.level.isOutsideBuildHeight(blockPos.getY()) || this.isSectionCompiledAndVisible(blockPos))
&& (
entity != camera.entity()
|| camera.isDetached()
|| camera.entity() instanceof LivingEntity && ((LivingEntity)camera.entity()).isSleeping()
)
&& (!(entity instanceof LocalPlayer) || camera.entity() == entity)) {
if (entity.tickCount == 0) {
entity.xOld = entity.getX();
entity.yOld = entity.getY();
entity.zOld = entity.getZ();
}
float partialEntity = deltaTracker.getGameTimeDeltaPartialTick(!tickRateManager.isEntityFrozen(entity));
EntityRenderState state = this.extractEntity(entity, partialEntity);
output.entityRenderStates.add(state);
if (state.appearsGlowing() && shouldShowEntityOutlines) {
output.haveGlowingEntities = true;
}
}
}
}
output.lastEntityRenderStateCount = output.entityRenderStates.size();
}
private void submitEntities(PoseStack poseStack, LevelRenderState levelRenderState, SubmitNodeCollector output) {
Vec3 cameraPos = levelRenderState.cameraRenderState.pos;
double camX = cameraPos.x();
double camY = cameraPos.y();
double camZ = cameraPos.z();
for (EntityRenderState state : levelRenderState.entityRenderStates) {
if (!levelRenderState.haveGlowingEntities) {
state.outlineColor = 0;
}
this.entityRenderDispatcher.submit(state, levelRenderState.cameraRenderState, state.x - camX, state.y - camY, state.z - camZ, poseStack, output);
}
}
private void extractVisibleBlockEntities(Camera camera, float deltaPartialTick, LevelRenderState levelRenderState) {
Vec3 cameraPos = camera.position();
double camX = cameraPos.x();
double camY = cameraPos.y();
double camZ = cameraPos.z();
PoseStack poseStack = new PoseStack();
for (SectionRenderDispatcher.RenderSection section : this.visibleSections) {
List<BlockEntity> renderableBlockEntities = section.getSectionMesh().getRenderableBlockEntities();
if (!renderableBlockEntities.isEmpty() && !(section.getVisibility(Util.getMillis()) < 0.3F)) {
for (BlockEntity blockEntity : renderableBlockEntities) {
BlockPos blockPos = blockEntity.getBlockPos();
SortedSet<BlockDestructionProgress> progresses = this.destructionProgress.get(blockPos.asLong());
ModelFeatureRenderer.CrumblingOverlay breakProgress;
if (progresses != null && !progresses.isEmpty()) {
poseStack.pushPose();
poseStack.translate(blockPos.getX() - camX, blockPos.getY() - camY, blockPos.getZ() - camZ);
breakProgress = new ModelFeatureRenderer.CrumblingOverlay(progresses.last().getProgress(), poseStack.last());
poseStack.popPose();
} else {
breakProgress = null;
}
BlockEntityRenderState state = this.blockEntityRenderDispatcher.tryExtractRenderState(blockEntity, deltaPartialTick, breakProgress);
if (state != null) {
levelRenderState.blockEntityRenderStates.add(state);
}
}
}
}
Iterator<BlockEntity> iterator = this.level.getGloballyRenderedBlockEntities().iterator();
while (iterator.hasNext()) {
BlockEntity blockEntity = iterator.next();
if (blockEntity.isRemoved()) {
iterator.remove();
} else {
BlockEntityRenderState state = this.blockEntityRenderDispatcher.tryExtractRenderState(blockEntity, deltaPartialTick, null);
if (state != null) {
levelRenderState.blockEntityRenderStates.add(state);
}
}
}
}
private void submitBlockEntities(PoseStack poseStack, LevelRenderState levelRenderState, SubmitNodeStorage submitNodeStorage) {
Vec3 cameraPos = levelRenderState.cameraRenderState.pos;
double camX = cameraPos.x();
double camY = cameraPos.y();
double camZ = cameraPos.z();
for (BlockEntityRenderState renderState : levelRenderState.blockEntityRenderStates) {
BlockPos blockPos = renderState.blockPos;
poseStack.pushPose();
poseStack.translate(blockPos.getX() - camX, blockPos.getY() - camY, blockPos.getZ() - camZ);
this.blockEntityRenderDispatcher.submit(renderState, poseStack, submitNodeStorage, levelRenderState.cameraRenderState);
poseStack.popPose();
}
}
private void extractBlockDestroyAnimation(Camera camera, LevelRenderState levelRenderState) {
Vec3 cameraPos = camera.position();
double camX = cameraPos.x();
double camY = cameraPos.y();
double camZ = cameraPos.z();
levelRenderState.blockBreakingRenderStates.clear();
for (Entry<SortedSet<BlockDestructionProgress>> entry : this.destructionProgress.long2ObjectEntrySet()) {
BlockPos pos = BlockPos.of(entry.getLongKey());
if (!(pos.distToCenterSqr(camX, camY, camZ) > 1024.0)) {
SortedSet<BlockDestructionProgress> progresses = entry.getValue();
if (progresses != null && !progresses.isEmpty()) {
int progress = progresses.last().getProgress();
levelRenderState.blockBreakingRenderStates.add(new BlockBreakingRenderState(pos, this.level.getBlockState(pos), progress));
}
}
}
}
private void submitBlockDestroyAnimation(PoseStack poseStack, SubmitNodeCollector submitNodeCollector, LevelRenderState levelRenderState) {
Vec3 cameraPos = levelRenderState.cameraRenderState.pos;
double camX = cameraPos.x();
double camY = cameraPos.y();
double camZ = cameraPos.z();
for (BlockBreakingRenderState state : levelRenderState.blockBreakingRenderStates) {
if (state.blockState().getRenderShape() == RenderShape.MODEL) {
BlockPos pos = state.blockPos();
poseStack.pushPose();
poseStack.translate(pos.getX() - camX, pos.getY() - camY, pos.getZ() - camZ);
BlockStateModel model = this.minecraft.getModelManager().getBlockStateModelSet().get(state.blockState());
submitNodeCollector.submitBreakingBlockModel(poseStack, model, state.blockState().getSeed(pos), state.progress());
poseStack.popPose();
}
}
}
private void extractBlockOutline(Camera camera, LevelRenderState levelRenderState) {
levelRenderState.blockOutlineRenderState = null;
if (this.minecraft.hitResult instanceof BlockHitResult blockHitResult) {
if (blockHitResult.getType() != HitResult.Type.MISS) {
BlockPos pos = blockHitResult.getBlockPos();
BlockState state = this.level.getBlockState(pos);
if (!state.isAir() && this.level.getWorldBorder().isWithinBounds(pos)) {
BlockStateModel blockStateModel = this.minecraft.getModelManager().getBlockStateModelSet().get(state);
boolean isBlockTranslucent = blockStateModel.hasMaterialFlag(1);
boolean highContrast = this.minecraft.options.highContrastBlockOutline().get();
CollisionContext context = CollisionContext.of(camera.entity());
VoxelShape shape = state.getShape(this.level, pos, context);
if (SharedConstants.DEBUG_SHAPES) {
VoxelShape collisionShape = state.getCollisionShape(this.level, pos, context);
VoxelShape occlusionShape = state.getOcclusionShape();
VoxelShape interactionShape = state.getInteractionShape(this.level, pos);
levelRenderState.blockOutlineRenderState = new BlockOutlineRenderState(
pos, isBlockTranslucent, highContrast, shape, collisionShape, occlusionShape, interactionShape
);
} else {
levelRenderState.blockOutlineRenderState = new BlockOutlineRenderState(pos, isBlockTranslucent, highContrast, shape);
}
}
}
}
}
private void renderBlockOutline(
MultiBufferSource.BufferSource bufferSource, PoseStack poseStack, boolean onlyTranslucentBlocks, LevelRenderState levelRenderState
) {
BlockOutlineRenderState state = levelRenderState.blockOutlineRenderState;
if (state != null) {
if (state.isTranslucent() == onlyTranslucentBlocks) {
Vec3 cameraPos = levelRenderState.cameraRenderState.pos;
if (state.highContrast()) {
VertexConsumer buffer = bufferSource.getBuffer(RenderTypes.secondaryBlockOutline());
this.renderHitOutline(poseStack, buffer, cameraPos.x, cameraPos.y, cameraPos.z, state, -16777216, 7.0F);
}
VertexConsumer buffer = bufferSource.getBuffer(RenderTypes.lines());
int outlineColor = state.highContrast() ? -11010079 : ARGB.black(102);
this.renderHitOutline(
poseStack,
buffer,
cameraPos.x,
cameraPos.y,
cameraPos.z,
state,
outlineColor,
this.minecraft.gameRenderer.getGameRenderState().windowRenderState.appropriateLineWidth
);
bufferSource.endLastBatch();
}
}
}
private void checkPoseStack(PoseStack poseStack) {
if (!poseStack.isEmpty()) {
throw new IllegalStateException("Pose stack not empty");
}
}
private EntityRenderState extractEntity(Entity entity, float partialTickTime) {
return this.entityRenderDispatcher.extractEntity(entity, partialTickTime);
}
private void scheduleTranslucentSectionResort(Vec3 cameraPos) {
if (!this.visibleSections.isEmpty()) {
BlockPos cameraBlockPos = BlockPos.containing(cameraPos);
boolean blockPosChanged = !cameraBlockPos.equals(this.lastTranslucentSortBlockPos);
TranslucencyPointOfView pointOfView = new TranslucencyPointOfView();
for (SectionRenderDispatcher.RenderSection section : this.nearbyVisibleSections) {
this.scheduleResort(section, pointOfView, cameraPos, blockPosChanged, true);
}
this.translucencyResortIterationIndex = this.translucencyResortIterationIndex % this.visibleSections.size();
int resortsLeft = Math.max(this.visibleSections.size() / 8, 15);
while (resortsLeft-- > 0) {
int index = this.translucencyResortIterationIndex++ % this.visibleSections.size();
this.scheduleResort(this.visibleSections.get(index), pointOfView, cameraPos, blockPosChanged, false);
}
this.lastTranslucentSortBlockPos = cameraBlockPos;
}
}
private void scheduleResort(
SectionRenderDispatcher.RenderSection section, TranslucencyPointOfView pointOfView, Vec3 cameraPos, boolean blockPosChanged, boolean isNearby
) {
pointOfView.set(cameraPos, section.getSectionNode());
boolean pointOfViewChanged = section.getSectionMesh().isDifferentPointOfView(pointOfView);
boolean resortBecauseBlockPosChanged = blockPosChanged && (pointOfView.isAxisAligned() || isNearby);
if ((resortBecauseBlockPosChanged || pointOfViewChanged) && !section.transparencyResortingScheduled() && section.hasTranslucentGeometry()) {
section.resortTransparency(this.sectionRenderDispatcher);
}
}
public ChunkSectionsToRender prepareChunkRenders(Matrix4fc modelViewMatrix) {
ObjectListIterator<SectionRenderDispatcher.RenderSection> iterator = this.visibleSections.listIterator(0);
EnumMap<ChunkSectionLayer, Int2ObjectOpenHashMap<List<RenderPass.Draw<GpuBufferSlice[]>>>> drawGroups = new EnumMap<>(ChunkSectionLayer.class);
int largestIndexCount = 0;
for (ChunkSectionLayer layer : ChunkSectionLayer.values()) {
drawGroups.put(layer, new Int2ObjectOpenHashMap<>());
}
List<DynamicUniforms.ChunkSectionInfo> sectionInfos = new ArrayList<>();
GpuTextureView blockAtlas = this.minecraft.getTextureManager().getTexture(TextureAtlas.LOCATION_BLOCKS).getTextureView();
int textureAtlasWidth = blockAtlas.getWidth(0);
int textureAtlasHeight = blockAtlas.getHeight(0);
if (this.sectionRenderDispatcher != null) {
this.sectionRenderDispatcher.lock();
try {
try (Zone ignored = Profiler.get().zone("Upload Global Buffers")) {
this.sectionRenderDispatcher.uploadGlobalGeomBuffersToGPU();
}
while (iterator.hasNext()) {
SectionRenderDispatcher.RenderSection section = iterator.next();
SectionMesh sectionMesh = section.getSectionMesh();
BlockPos renderOffset = section.getRenderOrigin();
long now = Util.getMillis();
int uboIndex = -1;
for (ChunkSectionLayer layer : ChunkSectionLayer.values()) {
SectionMesh.SectionDraw draw = sectionMesh.getSectionDraw(layer);
SectionRenderDispatcher.RenderSectionBufferSlice slice = this.sectionRenderDispatcher.getRenderSectionSlice(sectionMesh, layer);
if (slice != null && draw != null && (!draw.hasCustomIndexBuffer() || slice.indexBuffer() != null)) {
if (uboIndex == -1) {
uboIndex = sectionInfos.size();
sectionInfos.add(
new DynamicUniforms.ChunkSectionInfo(
new Matrix4f(modelViewMatrix),
renderOffset.getX(),
renderOffset.getY(),
renderOffset.getZ(),
section.getVisibility(now),
textureAtlasWidth,
textureAtlasHeight
)
);
}
int combinedHash = 173;
VertexFormat vertexFormat = layer.pipeline().getVertexFormat();
GpuBuffer vertexBuffer = slice.vertexBuffer();
if (layer != ChunkSectionLayer.TRANSLUCENT) {
combinedHash = 31 * combinedHash + vertexBuffer.hashCode();
}
int firstIndex = 0;
GpuBuffer indexBuffer;
VertexFormat.IndexType indexType;
if (!draw.hasCustomIndexBuffer()) {
if (draw.indexCount() > largestIndexCount) {
largestIndexCount = draw.indexCount();
}
indexBuffer = null;
indexType = null;
} else {
indexBuffer = slice.indexBuffer();
indexType = draw.indexType();
if (layer != ChunkSectionLayer.TRANSLUCENT) {
combinedHash = 31 * combinedHash + indexBuffer.hashCode();
combinedHash = 31 * combinedHash + indexType.hashCode();
}
firstIndex = (int)(slice.indexBufferOffset() / indexType.bytes);
}
int finalUboIndex = uboIndex;
int baseVertex = (int)(slice.vertexBufferOffset() / vertexFormat.getVertexSize());
List<RenderPass.Draw<GpuBufferSlice[]>> draws = drawGroups.get(layer).computeIfAbsent(combinedHash, var0 -> new ArrayList<>());
draws.add(
new RenderPass.Draw<>(
0,
vertexBuffer,
indexBuffer,
indexType,
firstIndex,
draw.indexCount(),
baseVertex,
(sectionUbos, uploader) -> uploader.upload("ChunkSection", sectionUbos[finalUboIndex])
)
);
}
}
}
} finally {
this.sectionRenderDispatcher.unlock();
}
}
GpuBufferSlice[] chunkSectionInfos = RenderSystem.getDynamicUniforms()
.writeChunkSections(sectionInfos.toArray(new DynamicUniforms.ChunkSectionInfo[0]));
return new ChunkSectionsToRender(blockAtlas, drawGroups, largestIndexCount, chunkSectionInfos);
}
public void endFrame() {
this.cloudRenderer.endFrame();
}
public void tick(Camera camera) {
if (this.level.tickRateManager().runsNormally()) {
this.ticks++;
}
this.weatherEffectRenderer
.tickRainParticles(this.level, camera, this.ticks, this.minecraft.options.particles().get(), this.minecraft.options.weatherRadius().get());
this.removeBlockBreakingProgress();
}
private void removeBlockBreakingProgress() {
if (this.ticks % 20 == 0) {
Iterator<BlockDestructionProgress> iterator = this.destroyingBlocks.values().iterator();
while (iterator.hasNext()) {
BlockDestructionProgress block = iterator.next();
int updatedRenderTick = block.getUpdatedRenderTick();
if (this.ticks - updatedRenderTick > 400) {
iterator.remove();
this.removeProgress(block);
}
}
}
}
private void removeProgress(BlockDestructionProgress block) {
long pos = block.getPos().asLong();
Set<BlockDestructionProgress> progresses = this.destructionProgress.get(pos);
progresses.remove(block);
if (progresses.isEmpty()) {
this.destructionProgress.remove(pos);
}
}
private void addSkyPass(FrameGraphBuilder frame, CameraRenderState cameraState, GpuBufferSlice skyFog) {
FogType fogType = cameraState.fogType;
if (fogType != FogType.POWDER_SNOW && fogType != FogType.LAVA && !cameraState.entityRenderState.doesMobEffectBlockSky) {
SkyRenderState state = this.levelRenderState.skyRenderState;
if (state.skybox != DimensionType.Skybox.NONE) {
SkyRenderer skyRenderer = this.skyRenderer;
if (skyRenderer != null) {
FramePass pass = frame.addPass("sky");
this.targets.main = pass.readsAndWrites(this.targets.main);
pass.executes(
() -> {
RenderSystem.setShaderFog(skyFog);
if (state.skybox == DimensionType.Skybox.END) {
skyRenderer.renderEndSky();
if (state.endFlashIntensity > 1.0E-5F) {
PoseStack poseStack = new PoseStack();
skyRenderer.renderEndFlash(poseStack, state.endFlashIntensity, state.endFlashXAngle, state.endFlashYAngle);
}
} else {
PoseStack poseStack = new PoseStack();
skyRenderer.renderSkyDisc(state.skyColor);
skyRenderer.renderSunriseAndSunset(poseStack, state.sunAngle, state.sunriseAndSunsetColor);
skyRenderer.renderSunMoonAndStars(
poseStack, state.sunAngle, state.moonAngle, state.starAngle, state.moonPhase, state.rainBrightness, state.starBrightness
);
if (state.shouldRenderDarkDisc) {
skyRenderer.renderDarkDisc();
}
}
}
);
}
}
}
}
private void compileSections(Camera camera) {
ProfilerFiller profiler = Profiler.get();
profiler.push("populateSectionsToCompile");
RenderRegionCache cache = new RenderRegionCache();
BlockPos cameraPosition = camera.blockPosition();
List<SectionRenderDispatcher.RenderSection> sectionsToCompile = Lists.newArrayList();
long fadeDuration = Mth.floor(this.minecraft.options.chunkSectionFadeInTime().get() * 1000.0);
for (SectionRenderDispatcher.RenderSection section : this.visibleSections) {
if (section.isDirty() && (section.getSectionMesh() != CompiledSectionMesh.UNCOMPILED || section.hasAllNeighbors())) {
BlockPos center = SectionPos.of(section.getSectionNode()).center();
double distSqr = center.distSqr(cameraPosition);
boolean isNearby = distSqr < 768.0;
boolean rebuildSync = false;
if (this.minecraft.options.prioritizeChunkUpdates().get() == PrioritizeChunkUpdates.NEARBY) {
rebuildSync = isNearby || section.isDirtyFromPlayer();
} else if (this.minecraft.options.prioritizeChunkUpdates().get() == PrioritizeChunkUpdates.PLAYER_AFFECTED) {
rebuildSync = section.isDirtyFromPlayer();
}
if (!isNearby && !section.wasPreviouslyEmpty()) {
section.setFadeDuration(fadeDuration);
} else {
section.setFadeDuration(0L);
}
section.setWasPreviouslyEmpty(false);
if (rebuildSync) {
profiler.push("compileSectionSynchronously");
this.sectionRenderDispatcher.rebuildSectionSync(section, cache);
section.setNotDirty();
profiler.pop();
} else {
sectionsToCompile.add(section);
}
}
}
profiler.popPush("scheduleAsyncCompile");
for (SectionRenderDispatcher.RenderSection renderSection : sectionsToCompile) {
renderSection.rebuildSectionAsync(cache);
renderSection.setNotDirty();
}
profiler.popPush("scheduleTranslucentResort");
this.scheduleTranslucentSectionResort(camera.position());
profiler.pop();
}
private void renderHitOutline(
PoseStack poseStack, VertexConsumer builder, double camX, double camY, double camZ, BlockOutlineRenderState state, int color, float width
) {
BlockPos pos = state.pos();
if (SharedConstants.DEBUG_SHAPES) {
ShapeRenderer.renderShape(
poseStack, builder, state.shape(), pos.getX() - camX, pos.getY() - camY, pos.getZ() - camZ, ARGB.colorFromFloat(1.0F, 1.0F, 1.0F, 1.0F), width
);
if (state.collisionShape() != null) {
ShapeRenderer.renderShape(
poseStack,
builder,
state.collisionShape(),
pos.getX() - camX,
pos.getY() - camY,
pos.getZ() - camZ,
ARGB.colorFromFloat(0.4F, 0.0F, 0.0F, 0.0F),
width
);
}
if (state.occlusionShape() != null) {
ShapeRenderer.renderShape(
poseStack,
builder,
state.occlusionShape(),
pos.getX() - camX,
pos.getY() - camY,
pos.getZ() - camZ,
ARGB.colorFromFloat(0.4F, 0.0F, 1.0F, 0.0F),
width
);
}
if (state.interactionShape() != null) {
ShapeRenderer.renderShape(
poseStack,
builder,
state.interactionShape(),
pos.getX() - camX,
pos.getY() - camY,
pos.getZ() - camZ,
ARGB.colorFromFloat(0.4F, 0.0F, 0.0F, 1.0F),
width
);
}
} else {
ShapeRenderer.renderShape(poseStack, builder, state.shape(), pos.getX() - camX, pos.getY() - camY, pos.getZ() - camZ, color, width);
}
}
public void blockChanged(BlockGetter level, BlockPos pos, BlockState old, BlockState current, @Block.UpdateFlags int updateFlags) {
this.setBlockDirty(pos, (updateFlags & 8) != 0);
}
private void setBlockDirty(BlockPos pos, boolean playerChanged) {
for (int z = pos.getZ() - 1; z <= pos.getZ() + 1; z++) {
for (int x = pos.getX() - 1; x <= pos.getX() + 1; x++) {
for (int y = pos.getY() - 1; y <= pos.getY() + 1; y++) {
this.setSectionDirty(SectionPos.blockToSectionCoord(x), SectionPos.blockToSectionCoord(y), SectionPos.blockToSectionCoord(z), playerChanged);
}
}
}
}
public void setBlocksDirty(int x0, int y0, int z0, int x1, int y1, int z1) {
for (int z = z0 - 1; z <= z1 + 1; z++) {
for (int x = x0 - 1; x <= x1 + 1; x++) {
for (int y = y0 - 1; y <= y1 + 1; y++) {
this.setSectionDirty(SectionPos.blockToSectionCoord(x), SectionPos.blockToSectionCoord(y), SectionPos.blockToSectionCoord(z));
}
}
}
}
public void setBlockDirty(BlockPos pos, BlockState oldState, BlockState newState) {
if (this.minecraft.getModelManager().requiresRender(oldState, newState)) {
this.setBlocksDirty(pos.getX(), pos.getY(), pos.getZ(), pos.getX(), pos.getY(), pos.getZ());
}
}
public void setSectionDirtyWithNeighbors(int sectionX, int sectionY, int sectionZ) {
this.setSectionRangeDirty(sectionX - 1, sectionY - 1, sectionZ - 1, sectionX + 1, sectionY + 1, sectionZ + 1);
}
public void setSectionRangeDirty(int minSectionX, int minSectionY, int minSectionZ, int maxSectionX, int maxSectionY, int maxSectionZ) {
for (int z = minSectionZ; z <= maxSectionZ; z++) {
for (int x = minSectionX; x <= maxSectionX; x++) {
for (int y = minSectionY; y <= maxSectionY; y++) {
this.setSectionDirty(x, y, z);
}
}
}
}
public void setSectionDirty(int sectionX, int sectionY, int sectionZ) {
this.setSectionDirty(sectionX, sectionY, sectionZ, false);
}
private void setSectionDirty(int sectionX, int sectionY, int sectionZ, boolean playerChanged) {
this.viewArea.setDirty(sectionX, sectionY, sectionZ, playerChanged);
}
public void onSectionBecomingNonEmpty(long sectionNode) {
SectionRenderDispatcher.RenderSection section = this.viewArea.getRenderSection(sectionNode);
if (section != null) {
this.sectionOcclusionGraph.schedulePropagationFrom(section);
section.setWasPreviouslyEmpty(true);
}
}
public void destroyBlockProgress(int id, BlockPos pos, int progress) {
if (progress >= 0 && progress < 10) {
BlockDestructionProgress entry = this.destroyingBlocks.get(id);
if (entry != null) {
this.removeProgress(entry);
}
if (entry == null || entry.getPos().getX() != pos.getX() || entry.getPos().getY() != pos.getY() || entry.getPos().getZ() != pos.getZ()) {
entry = new BlockDestructionProgress(id, pos);
this.destroyingBlocks.put(id, entry);
}
entry.setProgress(progress);
entry.updateTick(this.ticks);
this.destructionProgress.computeIfAbsent(entry.getPos().asLong(), k -> Sets.newTreeSet()).add(entry);
} else {
BlockDestructionProgress removed = this.destroyingBlocks.remove(id);
if (removed != null) {
this.removeProgress(removed);
}
}
}
public boolean hasRenderedAllSections() {
return this.sectionRenderDispatcher.isQueueEmpty();
}
public void onChunkReadyToRender(ChunkPos pos) {
this.sectionOcclusionGraph.onChunkReadyToRender(pos);
}
public void needsUpdate() {
this.sectionOcclusionGraph.invalidate();
this.cloudRenderer.markForRebuild();
}
public static int getLightCoords(BlockAndLightGetter level, BlockPos pos) {
return getLightCoords(LevelRenderer.BrightnessGetter.DEFAULT, level, level.getBlockState(pos), pos);
}
public static int getLightCoords(LevelRenderer.BrightnessGetter brightnessGetter, BlockAndLightGetter level, BlockState state, BlockPos pos) {
if (state.emissiveRendering(level, pos)) {
return 15728880;
} else {
int packedBrightness = brightnessGetter.packedBrightness(level, pos);
int block = LightCoordsUtil.block(packedBrightness);
int blockSelfEmission = state.getLightEmission();
return block < blockSelfEmission ? LightCoordsUtil.withBlock(packedBrightness, blockSelfEmission) : packedBrightness;
}
}
public boolean isSectionCompiledAndVisible(BlockPos blockPos) {
SectionRenderDispatcher.RenderSection renderSection = this.viewArea.getRenderSectionAt(blockPos);
return renderSection != null && renderSection.sectionMesh.get() != CompiledSectionMesh.UNCOMPILED
? renderSection.getVisibility(Util.getMillis()) >= 0.3F
: false;
}
public @Nullable RenderTarget entityOutlineTarget() {
return this.targets.entityOutline != null ? this.targets.entityOutline.get() : null;
}
public @Nullable RenderTarget getTranslucentTarget() {
return this.targets.translucent != null ? this.targets.translucent.get() : null;
}
public @Nullable RenderTarget getItemEntityTarget() {
return this.targets.itemEntity != null ? this.targets.itemEntity.get() : null;
}
public @Nullable RenderTarget getParticlesTarget() {
return this.targets.particles != null ? this.targets.particles.get() : null;
}
public @Nullable RenderTarget getWeatherTarget() {
return this.targets.weather != null ? this.targets.weather.get() : null;
}
public @Nullable RenderTarget getCloudsTarget() {
return this.targets.clouds != null ? this.targets.clouds.get() : null;
}
@VisibleForDebug
public ObjectArrayList<SectionRenderDispatcher.RenderSection> getVisibleSections() {
return this.visibleSections;
}
@VisibleForDebug
public SectionOcclusionGraph getSectionOcclusionGraph() {
return this.sectionOcclusionGraph;
}
public CloudRenderer getCloudRenderer() {
return this.cloudRenderer;
}
public Gizmos.TemporaryCollection collectPerFrameGizmos() {
return Gizmos.withCollector(this.collectedGizmos);
}
private void finalizeGizmoCollection() {
DrawableGizmoPrimitives standardPrimitives = new DrawableGizmoPrimitives();
DrawableGizmoPrimitives alwaysOnTopPrimitives = new DrawableGizmoPrimitives();
this.collectedGizmos.addTemporaryGizmos(this.minecraft.getPerTickGizmos());
IntegratedServer server = this.minecraft.getSingleplayerServer();
if (server != null) {
this.collectedGizmos.addTemporaryGizmos(server.getPerTickGizmos());
}
long currentMillis = Util.getMillis();
for (SimpleGizmoCollector.GizmoInstance instance : this.collectedGizmos.drainGizmos()) {
instance.gizmo().emit(instance.isAlwaysOnTop() ? alwaysOnTopPrimitives : standardPrimitives, instance.getAlphaMultiplier(currentMillis));
}
this.finalizedGizmos = new LevelRenderer.FinalizedGizmos(standardPrimitives, alwaysOnTopPrimitives);
}
@FunctionalInterface
@OnlyIn(Dist.CLIENT)
public interface BrightnessGetter {
LevelRenderer.BrightnessGetter DEFAULT = (level, pos) -> {
int sky = level.getBrightness(LightLayer.SKY, pos);
int block = level.getBrightness(LightLayer.BLOCK, pos);
return LightCoordsUtil.pack(block, sky);
};
int packedBrightness(BlockAndLightGetter level, BlockPos pos);
}
@OnlyIn(Dist.CLIENT)
private record FinalizedGizmos(DrawableGizmoPrimitives standardPrimitives, DrawableGizmoPrimitives alwaysOnTopPrimitives) {
}
}引用的其他类
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/方法调用/构造调用 - 关联成员:
FrameGraphBuilder(), FrameGraphBuilder.Inspector(), Inspector()
- 引用位置:
-
- 引用位置:
字段/返回值
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
TextureTarget()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
RenderTargetDescriptor()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
RenderSystem.getDevice(), RenderSystem.getDynamicUniforms(), RenderSystem.getModelViewStack(), RenderSystem.setShaderFog()
- 引用位置:
-
- 引用位置:
字段
- 引用位置:
-
- 引用位置:
参数/构造调用 - 关联成员:
PoseStack()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/字段/方法调用 - 关联成员:
Minecraft.getInstance(), Minecraft.useShaderTransparency()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
CloudRenderer()
- 引用位置:
-
- 引用位置:
方法调用/构造调用 - 关联成员:
ChunkSectionInfo(), DynamicUniforms.ChunkSectionInfo()
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
LevelTargetBundle()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
字段/构造调用/返回值 - 关联成员:
SectionOcclusionGraph()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ShapeRenderer.renderShape()
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
SkyRenderer()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
ViewArea()
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
WeatherEffectRenderer()
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
WorldBorderRenderer()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ChunkSectionLayer.values()
- 引用位置:
-
- 引用位置:
参数/构造调用/返回值 - 关联成员:
ChunkSectionsToRender()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
RenderRegionCache()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
SectionCompiler()
- 引用位置:
-
- 引用位置:
参数/字段/构造调用/返回值 - 关联成员:
SectionRenderDispatcher()
- 引用位置:
-
- 引用位置:
参数/构造调用 - 关联成员:
TranslucencyPointOfView()
- 引用位置:
-
- 引用位置:
参数/构造调用/返回值 - 关联成员:
Frustum()
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
DebugRenderer()
- 引用位置:
-
GameTestBlockHighlightRenderer
- 引用位置:
字段/构造调用 - 关联成员:
GameTestBlockHighlightRenderer()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
返回值
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
方法调用/构造调用 - 关联成员:
CrumblingOverlay(), ModelFeatureRenderer.CrumblingOverlay()
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
DrawableGizmoPrimitives()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
RenderTypes.lines(), RenderTypes.secondaryBlockOutline()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段
- 引用位置:
-
- 引用位置:
构造调用 - 关联成员:
BlockBreakingRenderState()
- 引用位置:
-
- 引用位置:
参数/构造调用 - 关联成员:
BlockOutlineRenderState()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
参数/字段/方法调用 - 关联成员:
BlockPos.containing(), BlockPos.of()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
SectionPos.blockToSectionCoord(), SectionPos.of(), SectionPos.posToSectionCoord()
- 引用位置:
-
- 引用位置:
方法调用/返回值 - 关联成员:
Gizmos.withCollector()
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
SimpleGizmoCollector()
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
Identifier.withDefaultNamespace()
- 引用位置:
-
- 引用位置:
参数/字段/构造调用 - 关联成员:
BlockDestructionProgress()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
实现
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
ARGB.alpha(), ARGB.black(), ARGB.colorFromFloat()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
LightCoordsUtil.block(), LightCoordsUtil.pack(), LightCoordsUtil.withBlock()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Mth.clamp(), Mth.floor()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Util.backgroundExecutor(), Util.getMillis()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
Profiler.get()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数/方法调用 - 关联成员:
Entity.setViewScale()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
LeavesBlock.setCutoutLeaves()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
CollisionContext.of()
- 引用位置: