GlProgram.java

com.mojang.blaze3d.opengl.GlProgram

信息

  • 全限定名:com.mojang.blaze3d.opengl.GlProgram
  • 类型:public class
  • 包:com.mojang.blaze3d.opengl
  • 源码路径:src/main/java/com/mojang/blaze3d/opengl/GlProgram.java
  • 起始行号:L22
  • 实现:AutoCloseable
  • 职责:

    TODO

字段/常量

  • LOGGER

    • 类型: Logger
    • 修饰符: private static final
    • 源码定位: L23
    • 说明:

      TODO

  • BUILT_IN_UNIFORMS

    • 类型: Set<String>
    • 修饰符: public static final
    • 源码定位: L24
    • 说明:

      TODO

  • INVALID_PROGRAM

    • 类型: GlProgram
    • 修饰符: public static final
    • 源码定位: L25
    • 说明:

      TODO

  • uniformsByName

    • 类型: Map<String,Uniform>
    • 修饰符: private final
    • 源码定位: L26
    • 说明:

      TODO

  • programId

    • 类型: int
    • 修饰符: private final
    • 源码定位: L27
    • 说明:

      TODO

  • debugLabel

    • 类型: String
    • 修饰符: private final
    • 源码定位: L28
    • 说明:

      TODO

内部类/嵌套类型

构造器

private GlProgram(int programId, String debugLabel) @ L30

  • 构造器名:GlProgram
  • 源码定位:L30
  • 修饰符:private

参数:

  • programId: int
  • debugLabel: String

说明:

TODO

方法

下面的方法块按源码顺序生成。

public static GlProgram link(GlShaderModule vertexShader, GlShaderModule fragmentShader, VertexFormat vertexFormat, String debugLabel) @ L35

  • 方法名:link
  • 源码定位:L35
  • 返回类型:GlProgram
  • 修饰符:public static

参数:

  • vertexShader: GlShaderModule
  • fragmentShader: GlShaderModule
  • vertexFormat: VertexFormat
  • debugLabel: String

说明:

TODO

public void setupUniforms(List<RenderPipeline.UniformDescription> uniforms, List<String> samplers) @ L73

  • 方法名:setupUniforms
  • 源码定位:L73
  • 返回类型:void
  • 修饰符:public

参数:

  • uniforms: List<RenderPipeline.UniformDescription>
  • samplers: List

说明:

TODO

public void close() @ L135

  • 方法名:close
  • 源码定位:L135
  • 返回类型:void
  • 修饰符:public

参数:

说明:

TODO

public Uniform getUniform(String name) @ L141

  • 方法名:getUniform
  • 源码定位:L141
  • 返回类型:Uniform
  • 修饰符:public

参数:

  • name: String

说明:

TODO

public int getProgramId() @ L146

  • 方法名:getProgramId
  • 源码定位:L146
  • 返回类型:int
  • 修饰符:public

参数:

说明:

TODO

public String toString() @ L151

  • 方法名:toString
  • 源码定位:L151
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public String getDebugLabel() @ L156

  • 方法名:getDebugLabel
  • 源码定位:L156
  • 返回类型:String
  • 修饰符:public

参数:

说明:

TODO

public Map<String,Uniform> getUniforms() @ L160

  • 方法名:getUniforms
  • 源码定位:L160
  • 返回类型:Map<String,Uniform>
  • 修饰符:public

参数:

说明:

TODO

代码

@OnlyIn(Dist.CLIENT)
public class GlProgram implements AutoCloseable {
    private static final Logger LOGGER = LogUtils.getLogger();
    public static final Set<String> BUILT_IN_UNIFORMS = Sets.newHashSet("Projection", "Lighting", "Fog", "Globals");
    public static final GlProgram INVALID_PROGRAM = new GlProgram(-1, "invalid");
    private final Map<String, Uniform> uniformsByName = new HashMap<>();
    private final int programId;
    private final String debugLabel;
 
    private GlProgram(int programId, String debugLabel) {
        this.programId = programId;
        this.debugLabel = debugLabel;
    }
 
    public static GlProgram link(GlShaderModule vertexShader, GlShaderModule fragmentShader, VertexFormat vertexFormat, String debugLabel) throws ShaderManager.CompilationException {
        int programId = GlStateManager.glCreateProgram();
        if (programId <= 0) {
            throw new ShaderManager.CompilationException("Could not create shader program (returned program ID " + programId + ")");
        } else {
            int attributeLocation = 0;
 
            for (String attributeName : vertexFormat.getElementAttributeNames()) {
                GlStateManager._glBindAttribLocation(programId, attributeLocation, attributeName);
                attributeLocation++;
            }
 
            GlStateManager.glAttachShader(programId, vertexShader.getShaderId());
            GlStateManager.glAttachShader(programId, fragmentShader.getShaderId());
            GlStateManager.glLinkProgram(programId);
            int linkStatus = GlStateManager.glGetProgrami(programId, 35714);
            String linkMessage = GlStateManager.glGetProgramInfoLog(programId, 32768);
            if (linkStatus != 0 && !linkMessage.contains("Failed for unknown reason")) {
                if (!linkMessage.isEmpty()) {
                    LOGGER.info(
                        "Info log when linking program containing VS {} and FS {}. Log output: {}", vertexShader.getId(), fragmentShader.getId(), linkMessage
                    );
                }
 
                return new GlProgram(programId, debugLabel);
            } else {
                throw new ShaderManager.CompilationException(
                    "Error encountered when linking program containing VS "
                        + vertexShader.getId()
                        + " and FS "
                        + fragmentShader.getId()
                        + ". Log output: "
                        + linkMessage
                );
            }
        }
    }
 
    public void setupUniforms(List<RenderPipeline.UniformDescription> uniforms, List<String> samplers) {
        int nextUboBinding = 0;
        int nextSamplerIndex = 0;
 
        for (RenderPipeline.UniformDescription uniformDescription : uniforms) {
            String uniformName = uniformDescription.name();
 
            Object var10000 = switch (uniformDescription.type()) {
                case UNIFORM_BUFFER -> {
                    int index = GL31.glGetUniformBlockIndex(this.programId, uniformName);
                    if (index == -1) {
                        yield null;
                    } else {
                        int uboBinding = nextUboBinding++;
                        GL31.glUniformBlockBinding(this.programId, index, uboBinding);
                        yield new Uniform.Ubo(uboBinding);
                    }
                }
                case TEXEL_BUFFER -> {
                    int location = GlStateManager._glGetUniformLocation(this.programId, uniformName);
                    if (location == -1) {
                        LOGGER.warn("{} shader program does not use utb {} defined in the pipeline. This might be a bug.", this.debugLabel, uniformName);
                        yield null;
                    } else {
                        int samplerIndex = nextSamplerIndex++;
                        yield new Uniform.Utb(location, samplerIndex, Objects.requireNonNull(uniformDescription.textureFormat()));
                    }
                }
            };
 
            Uniform uniform = (Uniform)var10000;
            if (uniform != null) {
                this.uniformsByName.put(uniformName, uniform);
            }
        }
 
        for (String sampler : samplers) {
            int location = GlStateManager._glGetUniformLocation(this.programId, sampler);
            if (location == -1) {
                LOGGER.warn("{} shader program does not use sampler {} defined in the pipeline. This might be a bug.", this.debugLabel, sampler);
            } else {
                int samplerIndex = nextSamplerIndex++;
                this.uniformsByName.put(sampler, new Uniform.Sampler(location, samplerIndex));
            }
        }
 
        int totalDefinedBlocks = GlStateManager.glGetProgrami(this.programId, 35382);
 
        for (int i = 0; i < totalDefinedBlocks; i++) {
            String name = GL31.glGetActiveUniformBlockName(this.programId, i);
            if (!this.uniformsByName.containsKey(name)) {
                if (!samplers.contains(name) && BUILT_IN_UNIFORMS.contains(name)) {
                    int uboBinding = nextUboBinding++;
                    GL31.glUniformBlockBinding(this.programId, i, uboBinding);
                    this.uniformsByName.put(name, new Uniform.Ubo(uboBinding));
                } else {
                    LOGGER.warn("Found unknown and unsupported uniform {} in {}", name, this.debugLabel);
                }
            }
        }
    }
 
    @Override
    public void close() {
        this.uniformsByName.values().forEach(Uniform::close);
        GlStateManager.glDeleteProgram(this.programId);
    }
 
    public @Nullable Uniform getUniform(String name) {
        RenderSystem.assertOnRenderThread();
        return this.uniformsByName.get(name);
    }
 
    @VisibleForTesting
    public int getProgramId() {
        return this.programId;
    }
 
    @Override
    public String toString() {
        return this.debugLabel;
    }
 
    public String getDebugLabel() {
        return this.debugLabel;
    }
 
    public Map<String, Uniform> getUniforms() {
        return this.uniformsByName;
    }
}

引用的其他类

  • GlShaderModule

    • 引用位置: 参数
  • GlStateManager

    • 引用位置: 方法调用
    • 关联成员: GlStateManager._glBindAttribLocation(), GlStateManager._glGetUniformLocation(), GlStateManager.glAttachShader(), GlStateManager.glCreateProgram(), GlStateManager.glDeleteProgram(), GlStateManager.glGetProgramInfoLog(), GlStateManager.glGetProgrami(), GlStateManager.glLinkProgram()
  • Uniform

    • 引用位置: 字段/方法调用/构造调用/返回值
    • 关联成员: Sampler(), Ubo(), Uniform.Sampler(), Uniform.Ubo(), Uniform.Utb(), Utb()
  • RenderPipeline

    • 引用位置: 参数
  • RenderSystem

    • 引用位置: 方法调用
    • 关联成员: RenderSystem.assertOnRenderThread()
  • VertexFormat

    • 引用位置: 参数
  • ShaderManager

    • 引用位置: 方法调用/构造调用
    • 关联成员: CompilationException(), ShaderManager.CompilationException()