ShaderManager.java
net.minecraft.client.renderer.ShaderManager
信息
- 全限定名:net.minecraft.client.renderer.ShaderManager
- 类型:public class
- 包:net.minecraft.client.renderer
- 源码路径:src/main/java/net/minecraft/client/renderer/ShaderManager.java
- 起始行号:L47
- 继承:SimplePreparableReloadListener<ShaderManager.Configs>
- 实现:AutoCloseable
- 职责:
TODO
字段/常量
-
LOGGER- 类型:
Logger - 修饰符:
private static final - 源码定位:
L48 - 说明:
TODO
- 类型:
-
MAX_LOG_LENGTH- 类型:
int - 修饰符:
public static final - 源码定位:
L49 - 说明:
TODO
- 类型:
-
SHADER_PATH- 类型:
String - 修饰符:
public static final - 源码定位:
L50 - 说明:
TODO
- 类型:
-
SHADER_INCLUDE_PATH- 类型:
String - 修饰符:
private static final - 源码定位:
L51 - 说明:
TODO
- 类型:
-
POST_CHAIN_ID_CONVERTER- 类型:
FileToIdConverter - 修饰符:
private static final - 源码定位:
L52 - 说明:
TODO
- 类型:
-
textureManager- 类型:
TextureManager - 修饰符:
private final - 源码定位:
L53 - 说明:
TODO
- 类型:
-
recoveryHandler- 类型:
Consumer<Exception> - 修饰符:
private final - 源码定位:
L54 - 说明:
TODO
- 类型:
-
compilationCache- 类型:
ShaderManager.CompilationCache - 修饰符:
private - 源码定位:
L55 - 说明:
TODO
- 类型:
-
postChainProjection- 类型:
Projection - 修饰符:
private final - 源码定位:
L56 - 说明:
TODO
- 类型:
-
postChainProjectionMatrixBuffer- 类型:
ProjectionMatrixBuffer - 修饰符:
private final - 源码定位:
L57 - 说明:
TODO
- 类型:
内部类/嵌套类型
-
net.minecraft.client.renderer.ShaderManager.CompilationCache- 类型:
class - 修饰符:
private - 源码定位:
L212 - 说明:
TODO
- 类型:
-
net.minecraft.client.renderer.ShaderManager.CompilationException- 类型:
class - 修饰符:
public static - 源码定位:
L263 - 说明:
TODO
- 类型:
-
net.minecraft.client.renderer.ShaderManager.Configs- 类型:
record - 修饰符:
public - 源码定位:
L270 - 说明:
TODO
- 类型:
-
net.minecraft.client.renderer.ShaderManager.ShaderSourceKey- 类型:
record - 修饰符:
private - 源码定位:
L275 - 说明:
TODO
- 类型:
构造器
public ShaderManager(TextureManager textureManager, Consumer<Exception> recoveryHandler) @ L59
- 构造器名:ShaderManager
- 源码定位:L59
- 修饰符:public
参数:
- textureManager: TextureManager
- recoveryHandler: Consumer
说明:
TODO
方法
下面的方法块按源码顺序生成。
protected ShaderManager.Configs prepare(ResourceManager manager, ProfilerFiller profiler) @ L65
- 方法名:prepare
- 源码定位:L65
- 返回类型:ShaderManager.Configs
- 修饰符:protected
参数:
- manager: ResourceManager
- profiler: ProfilerFiller
说明:
TODO
private static void loadShader(Identifier location, Resource resource, ShaderType type, Map<Identifier,Resource> files, Builder<ShaderManager.ShaderSourceKey,String> output) @ L86
- 方法名:loadShader
- 源码定位:L86
- 返回类型:void
- 修饰符:private static
参数:
- location: Identifier
- resource: Resource
- type: ShaderType
- files: Map<Identifier,Resource>
- output: Builder<ShaderManager.ShaderSourceKey,String>
说明:
TODO
private static GlslPreprocessor createPreprocessor(Map<Identifier,Resource> files, Identifier location) @ L100
- 方法名:createPreprocessor
- 源码定位:L100
- 返回类型:GlslPreprocessor
- 修饰符:private static
参数:
- files: Map<Identifier,Resource>
- location: Identifier
说明:
TODO
private static void loadPostChain(Identifier location, Resource resource, Builder<Identifier,PostChainConfig> output) @ L138
- 方法名:loadPostChain
- 源码定位:L138
- 返回类型:void
- 修饰符:private static
参数:
- location: Identifier
- resource: Resource
- output: Builder<Identifier,PostChainConfig>
说明:
TODO
private static boolean isShader(Identifier location) @ L149
- 方法名:isShader
- 源码定位:L149
- 返回类型:boolean
- 修饰符:private static
参数:
- location: Identifier
说明:
TODO
protected void apply(ShaderManager.Configs preparations, ResourceManager manager, ProfilerFiller profiler) @ L153
- 方法名:apply
- 源码定位:L153
- 返回类型:void
- 修饰符:protected
参数:
- preparations: ShaderManager.Configs
- manager: ResourceManager
- profiler: ProfilerFiller
说明:
TODO
public String getName() @ L178
- 方法名:getName
- 源码定位:L178
- 返回类型:String
- 修饰符:public
参数:
- 无
说明:
TODO
private void tryTriggerRecovery(Exception exception) @ L183
- 方法名:tryTriggerRecovery
- 源码定位:L183
- 返回类型:void
- 修饰符:private
参数:
- exception: Exception
说明:
TODO
public PostChain getPostChain(Identifier id, Set<Identifier> allowedTargets) @ L190
- 方法名:getPostChain
- 源码定位:L190
- 返回类型:PostChain
- 修饰符:public
参数:
- id: Identifier
- allowedTargets: Set
说明:
TODO
public void close() @ L201
- 方法名:close
- 源码定位:L201
- 返回类型:void
- 修饰符:public
参数:
- 无
说明:
TODO
public String getShader(Identifier id, ShaderType type) @ L207
- 方法名:getShader
- 源码定位:L207
- 返回类型:String
- 修饰符:public
参数:
- id: Identifier
- type: ShaderType
说明:
TODO
代码
@OnlyIn(Dist.CLIENT)
public class ShaderManager extends SimplePreparableReloadListener<ShaderManager.Configs> implements AutoCloseable {
private static final Logger LOGGER = LogUtils.getLogger();
public static final int MAX_LOG_LENGTH = 32768;
public static final String SHADER_PATH = "shaders";
private static final String SHADER_INCLUDE_PATH = "shaders/include/";
private static final FileToIdConverter POST_CHAIN_ID_CONVERTER = FileToIdConverter.json("post_effect");
private final TextureManager textureManager;
private final Consumer<Exception> recoveryHandler;
private ShaderManager.CompilationCache compilationCache = new ShaderManager.CompilationCache(ShaderManager.Configs.EMPTY);
private final Projection postChainProjection = new Projection();
private final ProjectionMatrixBuffer postChainProjectionMatrixBuffer = new ProjectionMatrixBuffer("post");
public ShaderManager(TextureManager textureManager, Consumer<Exception> recoveryHandler) {
this.textureManager = textureManager;
this.recoveryHandler = recoveryHandler;
this.postChainProjection.setupOrtho(0.1F, 1000.0F, 1.0F, 1.0F, false);
}
protected ShaderManager.Configs prepare(ResourceManager manager, ProfilerFiller profiler) {
Builder<ShaderManager.ShaderSourceKey, String> shaderSources = ImmutableMap.builder();
Map<Identifier, Resource> files = manager.listResources("shaders", ShaderManager::isShader);
for (Entry<Identifier, Resource> entry : files.entrySet()) {
Identifier location = entry.getKey();
ShaderType shaderType = ShaderType.byLocation(location);
if (shaderType != null) {
loadShader(location, entry.getValue(), shaderType, files, shaderSources);
}
}
Builder<Identifier, PostChainConfig> postChains = ImmutableMap.builder();
for (Entry<Identifier, Resource> entryx : POST_CHAIN_ID_CONVERTER.listMatchingResources(manager).entrySet()) {
loadPostChain(entryx.getKey(), entryx.getValue(), postChains);
}
return new ShaderManager.Configs(shaderSources.build(), postChains.build());
}
private static void loadShader(
Identifier location, Resource resource, ShaderType type, Map<Identifier, Resource> files, Builder<ShaderManager.ShaderSourceKey, String> output
) {
Identifier id = type.idConverter().fileToId(location);
GlslPreprocessor preprocessor = createPreprocessor(files, location);
try (Reader reader = resource.openAsReader()) {
String source = IOUtils.toString(reader);
output.put(new ShaderManager.ShaderSourceKey(id, type), String.join("", preprocessor.process(source)));
} catch (IOException var12) {
LOGGER.error("Failed to load shader source at {}", location, var12);
}
}
private static GlslPreprocessor createPreprocessor(Map<Identifier, Resource> files, Identifier location) {
final Identifier parentLocation = location.withPath(FileUtil::getFullResourcePath);
return new GlslPreprocessor() {
private final Set<Identifier> importedLocations = new ObjectArraySet<>();
@Override
public @Nullable String applyImport(boolean isRelative, String path) {
Identifier locationx;
try {
if (isRelative) {
locationx = parentLocation.withPath(parentPath -> FileUtil.normalizeResourcePath(parentPath + path));
} else {
locationx = Identifier.parse(path).withPrefix("shaders/include/");
}
} catch (IdentifierException var8) {
ShaderManager.LOGGER.error("Malformed GLSL import {}: {}", path, var8.getMessage());
return "#error " + var8.getMessage();
}
if (!this.importedLocations.add(locationx)) {
return null;
} else {
try {
String var5;
try (Reader importResource = files.get(locationx).openAsReader()) {
var5 = IOUtils.toString(importResource);
}
return var5;
} catch (IOException var10) {
ShaderManager.LOGGER.error("Could not open GLSL import {}: {}", locationx, var10.getMessage());
return "#error " + var10.getMessage();
}
}
}
};
}
private static void loadPostChain(Identifier location, Resource resource, Builder<Identifier, PostChainConfig> output) {
Identifier id = POST_CHAIN_ID_CONVERTER.fileToId(location);
try (Reader reader = resource.openAsReader()) {
JsonElement json = StrictJsonParser.parse(reader);
output.put(id, PostChainConfig.CODEC.parse(JsonOps.INSTANCE, json).getOrThrow(JsonSyntaxException::new));
} catch (JsonParseException | IOException var9) {
LOGGER.error("Failed to parse post chain at {}", location, var9);
}
}
private static boolean isShader(Identifier location) {
return ShaderType.byLocation(location) != null || location.getPath().endsWith(".glsl");
}
protected void apply(ShaderManager.Configs preparations, ResourceManager manager, ProfilerFiller profiler) {
ShaderManager.CompilationCache newCompilationCache = new ShaderManager.CompilationCache(preparations);
Set<RenderPipeline> pipelinesToPreload = new HashSet<>(RenderPipelines.getStaticPipelines());
List<Identifier> failedLoads = new ArrayList<>();
GpuDevice device = RenderSystem.getDevice();
device.clearPipelineCache();
for (RenderPipeline pipeline : pipelinesToPreload) {
CompiledRenderPipeline compiled = device.precompilePipeline(pipeline, newCompilationCache::getShaderSource);
if (!compiled.isValid()) {
failedLoads.add(pipeline.getLocation());
}
}
if (!failedLoads.isEmpty()) {
device.clearPipelineCache();
throw new RuntimeException(
"Failed to load required shader programs:\n" + failedLoads.stream().map(entry -> " - " + entry).collect(Collectors.joining("\n"))
);
} else {
this.compilationCache.close();
this.compilationCache = newCompilationCache;
}
}
@Override
public String getName() {
return "Shader Loader";
}
private void tryTriggerRecovery(Exception exception) {
if (!this.compilationCache.triggeredRecovery) {
this.recoveryHandler.accept(exception);
this.compilationCache.triggeredRecovery = true;
}
}
public @Nullable PostChain getPostChain(Identifier id, Set<Identifier> allowedTargets) {
try {
return this.compilationCache.getOrLoadPostChain(id, allowedTargets);
} catch (ShaderManager.CompilationException var4) {
LOGGER.error("Failed to load post chain: {}", id, var4);
this.compilationCache.postChains.put(id, Optional.empty());
this.tryTriggerRecovery(var4);
return null;
}
}
@Override
public void close() {
this.compilationCache.close();
this.postChainProjectionMatrixBuffer.close();
}
public @Nullable String getShader(Identifier id, ShaderType type) {
return this.compilationCache.getShaderSource(id, type);
}
@OnlyIn(Dist.CLIENT)
private class CompilationCache implements AutoCloseable {
private final ShaderManager.Configs configs;
private final Map<Identifier, Optional<PostChain>> postChains;
private boolean triggeredRecovery;
private CompilationCache(ShaderManager.Configs configs) {
Objects.requireNonNull(ShaderManager.this);
super();
this.postChains = new HashMap<>();
this.configs = configs;
}
public @Nullable PostChain getOrLoadPostChain(Identifier id, Set<Identifier> allowedTargets) throws ShaderManager.CompilationException {
Optional<PostChain> cached = this.postChains.get(id);
if (cached != null) {
return cached.orElse(null);
} else {
PostChain postChain = this.loadPostChain(id, allowedTargets);
this.postChains.put(id, Optional.of(postChain));
return postChain;
}
}
private PostChain loadPostChain(Identifier id, Set<Identifier> allowedTargets) throws ShaderManager.CompilationException {
PostChainConfig config = this.configs.postChains.get(id);
if (config == null) {
throw new ShaderManager.CompilationException("Could not find post chain with id: " + id);
} else {
return PostChain.load(
config,
ShaderManager.this.textureManager,
allowedTargets,
id,
ShaderManager.this.postChainProjection,
ShaderManager.this.postChainProjectionMatrixBuffer
);
}
}
@Override
public void close() {
this.postChains.values().forEach(chain -> chain.ifPresent(PostChain::close));
this.postChains.clear();
}
public @Nullable String getShaderSource(Identifier id, ShaderType type) {
return this.configs.shaderSources.get(new ShaderManager.ShaderSourceKey(id, type));
}
}
@OnlyIn(Dist.CLIENT)
public static class CompilationException extends Exception {
public CompilationException(String message) {
super(message);
}
}
@OnlyIn(Dist.CLIENT)
public record Configs(Map<ShaderManager.ShaderSourceKey, String> shaderSources, Map<Identifier, PostChainConfig> postChains) {
public static final ShaderManager.Configs EMPTY = new ShaderManager.Configs(Map.of(), Map.of());
}
@OnlyIn(Dist.CLIENT)
private record ShaderSourceKey(Identifier id, ShaderType type) {
@Override
public String toString() {
return this.id + " (" + this.type + ")";
}
}
}引用的其他类
-
- 引用位置:
构造调用/返回值 - 关联成员:
GlslPreprocessor()
- 引用位置:
-
- 引用位置:
参数/方法调用 - 关联成员:
ShaderType.byLocation()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
RenderSystem.getDevice()
- 引用位置:
-
- 引用位置:
方法调用/返回值 - 关联成员:
PostChain.load()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
Projection()
- 引用位置:
-
- 引用位置:
字段/构造调用 - 关联成员:
ProjectionMatrixBuffer()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
RenderPipelines.getStaticPipelines()
- 引用位置:
-
- 引用位置:
参数/字段
- 引用位置:
-
- 引用位置:
字段/方法调用 - 关联成员:
FileToIdConverter.json()
- 引用位置:
-
- 引用位置:
参数/方法调用 - 关联成员:
Identifier.parse()
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
- 引用位置:
参数
- 引用位置:
-
SimplePreparableReloadListener
- 引用位置:
继承
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
FileUtil.normalizeResourcePath()
- 引用位置:
-
- 引用位置:
方法调用 - 关联成员:
StrictJsonParser.parse()
- 引用位置:
-
- 引用位置:
参数
- 引用位置: