mirror of
https://github.com/Jozufozu/Flywheel.git
synced 2024-12-27 23:47:09 +01:00
Update uniform providers (again)
- Remove uniform api. - Do not generate uniform interface blocks. - Move uniform shader into internal/ and manually include it in the api impl headers. - Add flw_ prefix to existing uniforms. - Separate fog uniforms into their own UBO, uploaded in FogUpdateMixin. - Drastically simplify UniformBuffer. - Do not poll for uniform buffer updates. Instead, do the upload at the beginning of a frame when the engine is flushing.
This commit is contained in:
parent
3376bf9809
commit
655712aadf
31 changed files with 265 additions and 473 deletions
|
@ -10,7 +10,7 @@ import com.jozufozu.flywheel.api.visualization.VisualizationManager;
|
||||||
import com.jozufozu.flywheel.backend.Backends;
|
import com.jozufozu.flywheel.backend.Backends;
|
||||||
import com.jozufozu.flywheel.backend.ShaderIndices;
|
import com.jozufozu.flywheel.backend.ShaderIndices;
|
||||||
import com.jozufozu.flywheel.backend.compile.FlwPrograms;
|
import com.jozufozu.flywheel.backend.compile.FlwPrograms;
|
||||||
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
|
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
||||||
import com.jozufozu.flywheel.config.BackendArgument;
|
import com.jozufozu.flywheel.config.BackendArgument;
|
||||||
import com.jozufozu.flywheel.config.FlwCommands;
|
import com.jozufozu.flywheel.config.FlwCommands;
|
||||||
import com.jozufozu.flywheel.config.FlwConfig;
|
import com.jozufozu.flywheel.config.FlwConfig;
|
||||||
|
@ -95,7 +95,7 @@ public class Flywheel {
|
||||||
|
|
||||||
forgeEventBus.addListener(FlwCommands::registerClientCommands);
|
forgeEventBus.addListener(FlwCommands::registerClientCommands);
|
||||||
|
|
||||||
forgeEventBus.addListener(UniformBuffer::onReloadLevelRenderer);
|
forgeEventBus.addListener(Uniforms::onReloadLevelRenderer);
|
||||||
|
|
||||||
forgeEventBus.addListener(LightUpdater::onClientTick);
|
forgeEventBus.addListener(LightUpdater::onClientTick);
|
||||||
forgeEventBus.addListener((LevelEvent.Unload e) -> LevelAttached.onUnloadLevel(e));
|
forgeEventBus.addListener((LevelEvent.Unload e) -> LevelAttached.onUnloadLevel(e));
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
package com.jozufozu.flywheel.api.uniform;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.registry.Registry;
|
|
||||||
import com.jozufozu.flywheel.impl.RegistryImpl;
|
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
public interface ShaderUniforms {
|
|
||||||
static Registry<ShaderUniforms> REGISTRY = RegistryImpl.createForShaderUniforms();
|
|
||||||
|
|
||||||
Provider activate(long ptr);
|
|
||||||
|
|
||||||
ResourceLocation uniformShader();
|
|
||||||
|
|
||||||
int byteSize();
|
|
||||||
|
|
||||||
interface Provider {
|
|
||||||
/**
|
|
||||||
* Delete this provider.<p>
|
|
||||||
* <p>
|
|
||||||
* Do not free the ptr passed to {@link #activate(long)}.<br>
|
|
||||||
* Clean up other resources, and unsubscribe from events.
|
|
||||||
*/
|
|
||||||
void delete();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Poll the provider for changes.
|
|
||||||
*
|
|
||||||
* @return {@code true} if the provider updated its backing store.
|
|
||||||
*/
|
|
||||||
boolean poll();
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,10 +6,8 @@ import com.google.common.collect.ImmutableList;
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.context.Context;
|
import com.jozufozu.flywheel.api.context.Context;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
|
|
||||||
import com.jozufozu.flywheel.backend.ShaderIndices;
|
import com.jozufozu.flywheel.backend.ShaderIndices;
|
||||||
import com.jozufozu.flywheel.backend.compile.component.UberShaderComponent;
|
import com.jozufozu.flywheel.backend.compile.component.UberShaderComponent;
|
||||||
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
|
|
||||||
import com.jozufozu.flywheel.backend.compile.core.CompilerStats;
|
import com.jozufozu.flywheel.backend.compile.core.CompilerStats;
|
||||||
import com.jozufozu.flywheel.backend.compile.core.SourceLoader;
|
import com.jozufozu.flywheel.backend.compile.core.SourceLoader;
|
||||||
import com.jozufozu.flywheel.backend.glsl.ShaderSources;
|
import com.jozufozu.flywheel.backend.glsl.ShaderSources;
|
||||||
|
@ -30,12 +28,11 @@ public final class FlwPrograms {
|
||||||
var loadChecker = new SourceLoader(sources, preLoadStats);
|
var loadChecker = new SourceLoader(sources, preLoadStats);
|
||||||
|
|
||||||
var pipelineKeys = createPipelineKeys();
|
var pipelineKeys = createPipelineKeys();
|
||||||
var uniformComponent = createUniformComponent(loadChecker);
|
|
||||||
List<SourceComponent> vertexComponents = List.of(createVertexMaterialComponent(loadChecker));
|
List<SourceComponent> vertexComponents = List.of(createVertexMaterialComponent(loadChecker));
|
||||||
List<SourceComponent> fragmentComponents = List.of(createFragmentMaterialComponent(loadChecker), createFogComponent(loadChecker), createCutoutComponent(loadChecker));
|
List<SourceComponent> fragmentComponents = List.of(createFragmentMaterialComponent(loadChecker), createFogComponent(loadChecker), createCutoutComponent(loadChecker));
|
||||||
|
|
||||||
InstancingPrograms.reload(sources, pipelineKeys, uniformComponent, vertexComponents, fragmentComponents);
|
InstancingPrograms.reload(sources, pipelineKeys, vertexComponents, fragmentComponents);
|
||||||
IndirectPrograms.reload(sources, pipelineKeys, uniformComponent, vertexComponents, fragmentComponents);
|
IndirectPrograms.reload(sources, pipelineKeys, vertexComponents, fragmentComponents);
|
||||||
|
|
||||||
if (preLoadStats.errored()) {
|
if (preLoadStats.errored()) {
|
||||||
Flywheel.LOGGER.error(preLoadStats.generateErrorLog());
|
Flywheel.LOGGER.error(preLoadStats.generateErrorLog());
|
||||||
|
@ -96,15 +93,6 @@ public final class FlwPrograms {
|
||||||
.build(loadChecker);
|
.build(loadChecker);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static UniformComponent createUniformComponent(SourceLoader loadChecker) {
|
|
||||||
return UniformComponent.builder(Flywheel.rl("uniforms"))
|
|
||||||
.sources(ShaderUniforms.REGISTRY.getAll()
|
|
||||||
.stream()
|
|
||||||
.map(ShaderUniforms::uniformShader)
|
|
||||||
.toList())
|
|
||||||
.build(loadChecker);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class ResourceReloadListener implements ResourceManagerReloadListener {
|
public static class ResourceReloadListener implements ResourceManagerReloadListener {
|
||||||
public static final ResourceReloadListener INSTANCE = new ResourceReloadListener();
|
public static final ResourceReloadListener INSTANCE = new ResourceReloadListener();
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,6 @@ import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.context.Context;
|
import com.jozufozu.flywheel.api.context.Context;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.backend.compile.component.IndirectComponent;
|
import com.jozufozu.flywheel.backend.compile.component.IndirectComponent;
|
||||||
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
|
|
||||||
import com.jozufozu.flywheel.backend.compile.core.CompilationHarness;
|
import com.jozufozu.flywheel.backend.compile.core.CompilationHarness;
|
||||||
import com.jozufozu.flywheel.backend.compile.core.Compile;
|
import com.jozufozu.flywheel.backend.compile.core.Compile;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlCompat;
|
import com.jozufozu.flywheel.backend.gl.GlCompat;
|
||||||
|
@ -45,11 +44,11 @@ public class IndirectPrograms extends AbstractPrograms {
|
||||||
this.scatter = scatter;
|
this.scatter = scatter;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reload(ShaderSources sources, ImmutableList<PipelineProgramKey> pipelineKeys, UniformComponent uniformComponent, List<SourceComponent> vertexComponents, List<SourceComponent> fragmentComponents) {
|
static void reload(ShaderSources sources, ImmutableList<PipelineProgramKey> pipelineKeys, List<SourceComponent> vertexComponents, List<SourceComponent> fragmentComponents) {
|
||||||
IndirectPrograms newInstance = null;
|
IndirectPrograms newInstance = null;
|
||||||
|
|
||||||
var pipelineCompiler = PipelineCompiler.create(sources, Pipelines.INDIRECT, uniformComponent, vertexComponents, fragmentComponents);
|
var pipelineCompiler = PipelineCompiler.create(sources, Pipelines.INDIRECT, vertexComponents, fragmentComponents);
|
||||||
var cullingCompiler = createCullingCompiler(uniformComponent, sources);
|
var cullingCompiler = createCullingCompiler(sources);
|
||||||
var applyCompiler = createUtilCompiler(sources);
|
var applyCompiler = createUtilCompiler(sources);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -71,15 +70,14 @@ public class IndirectPrograms extends AbstractPrograms {
|
||||||
setInstance(newInstance);
|
setInstance(newInstance);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static CompilationHarness<InstanceType<?>> createCullingCompiler(UniformComponent uniformComponent, ShaderSources sources) {
|
private static CompilationHarness<InstanceType<?>> createCullingCompiler(ShaderSources sources) {
|
||||||
return CULL.program()
|
return CULL.program()
|
||||||
.link(CULL.shader(GlslVersion.V460, ShaderType.COMPUTE)
|
.link(CULL.shader(GlslVersion.V460, ShaderType.COMPUTE)
|
||||||
.define("_FLW_SUBGROUP_SIZE", GlCompat.SUBGROUP_SIZE)
|
.define("_FLW_SUBGROUP_SIZE", GlCompat.SUBGROUP_SIZE)
|
||||||
.withComponent(uniformComponent)
|
|
||||||
.withComponent(IndirectComponent::create)
|
.withComponent(IndirectComponent::create)
|
||||||
.withResource(InstanceType::cullShader)
|
.withResource(InstanceType::cullShader)
|
||||||
.withResource(CULL_SHADER_MAIN))
|
.withResource(CULL_SHADER_MAIN))
|
||||||
.then((key, program) -> program.setUniformBlockBinding("FlwUniforms", 0))
|
.then((key, program) -> program.setUniformBlockBinding("_FlwFrameUniforms", 0))
|
||||||
.harness(sources);
|
.harness(sources);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,6 @@ import com.google.common.collect.ImmutableList;
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
import com.jozufozu.flywheel.Flywheel;
|
||||||
import com.jozufozu.flywheel.api.context.Context;
|
import com.jozufozu.flywheel.api.context.Context;
|
||||||
import com.jozufozu.flywheel.api.instance.InstanceType;
|
import com.jozufozu.flywheel.api.instance.InstanceType;
|
||||||
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
||||||
import com.jozufozu.flywheel.backend.glsl.ShaderSources;
|
import com.jozufozu.flywheel.backend.glsl.ShaderSources;
|
||||||
import com.jozufozu.flywheel.backend.glsl.SourceComponent;
|
import com.jozufozu.flywheel.backend.glsl.SourceComponent;
|
||||||
|
@ -24,10 +23,10 @@ public class InstancingPrograms extends AbstractPrograms {
|
||||||
this.pipeline = pipeline;
|
this.pipeline = pipeline;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void reload(ShaderSources sources, ImmutableList<PipelineProgramKey> pipelineKeys, UniformComponent uniformComponent, List<SourceComponent> vertexComponents, List<SourceComponent> fragmentComponents) {
|
static void reload(ShaderSources sources, ImmutableList<PipelineProgramKey> pipelineKeys, List<SourceComponent> vertexComponents, List<SourceComponent> fragmentComponents) {
|
||||||
InstancingPrograms newInstance = null;
|
InstancingPrograms newInstance = null;
|
||||||
|
|
||||||
var pipelineCompiler = PipelineCompiler.create(sources, Pipelines.INSTANCED_ARRAYS, uniformComponent, vertexComponents, fragmentComponents);
|
var pipelineCompiler = PipelineCompiler.create(sources, Pipelines.INSTANCED_ARRAYS, vertexComponents, fragmentComponents);
|
||||||
|
|
||||||
try {
|
try {
|
||||||
var pipelineResult = pipelineCompiler.compileAndReportErrors(pipelineKeys);
|
var pipelineResult = pipelineCompiler.compileAndReportErrors(pipelineKeys);
|
||||||
|
|
|
@ -3,7 +3,6 @@ package com.jozufozu.flywheel.backend.compile;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.backend.InternalVertex;
|
import com.jozufozu.flywheel.backend.InternalVertex;
|
||||||
import com.jozufozu.flywheel.backend.compile.component.UniformComponent;
|
|
||||||
import com.jozufozu.flywheel.backend.compile.core.CompilationHarness;
|
import com.jozufozu.flywheel.backend.compile.core.CompilationHarness;
|
||||||
import com.jozufozu.flywheel.backend.compile.core.Compile;
|
import com.jozufozu.flywheel.backend.compile.core.Compile;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
import com.jozufozu.flywheel.backend.gl.shader.ShaderType;
|
||||||
|
@ -13,10 +12,9 @@ import com.jozufozu.flywheel.backend.glsl.SourceComponent;
|
||||||
public class PipelineCompiler {
|
public class PipelineCompiler {
|
||||||
private static final Compile<PipelineProgramKey> PIPELINE = new Compile<>();
|
private static final Compile<PipelineProgramKey> PIPELINE = new Compile<>();
|
||||||
|
|
||||||
static CompilationHarness<PipelineProgramKey> create(ShaderSources sources, Pipeline pipeline, UniformComponent uniformComponent, List<SourceComponent> vertexComponents, List<SourceComponent> fragmentComponents) {
|
static CompilationHarness<PipelineProgramKey> create(ShaderSources sources, Pipeline pipeline, List<SourceComponent> vertexComponents, List<SourceComponent> fragmentComponents) {
|
||||||
return PIPELINE.program()
|
return PIPELINE.program()
|
||||||
.link(PIPELINE.shader(pipeline.glslVersion(), ShaderType.VERTEX)
|
.link(PIPELINE.shader(pipeline.glslVersion(), ShaderType.VERTEX)
|
||||||
.withComponent(uniformComponent)
|
|
||||||
.withResource(pipeline.vertexApiImpl())
|
.withResource(pipeline.vertexApiImpl())
|
||||||
.withResource(InternalVertex.LAYOUT_SHADER)
|
.withResource(InternalVertex.LAYOUT_SHADER)
|
||||||
.withComponent(key -> pipeline.assembler()
|
.withComponent(key -> pipeline.assembler()
|
||||||
|
@ -29,7 +27,6 @@ public class PipelineCompiler {
|
||||||
.withResource(pipeline.vertexMain()))
|
.withResource(pipeline.vertexMain()))
|
||||||
.link(PIPELINE.shader(pipeline.glslVersion(), ShaderType.FRAGMENT)
|
.link(PIPELINE.shader(pipeline.glslVersion(), ShaderType.FRAGMENT)
|
||||||
.enableExtension("GL_ARB_conservative_depth")
|
.enableExtension("GL_ARB_conservative_depth")
|
||||||
.withComponent(uniformComponent)
|
|
||||||
.withResource(pipeline.fragmentApiImpl())
|
.withResource(pipeline.fragmentApiImpl())
|
||||||
.withComponents(fragmentComponents)
|
.withComponents(fragmentComponents)
|
||||||
.withResource(key -> key.contextShader()
|
.withResource(key -> key.contextShader()
|
||||||
|
@ -38,7 +35,8 @@ public class PipelineCompiler {
|
||||||
.then((key, program) -> {
|
.then((key, program) -> {
|
||||||
key.contextShader()
|
key.contextShader()
|
||||||
.onProgramLink(program);
|
.onProgramLink(program);
|
||||||
program.setUniformBlockBinding("FlwUniforms", 0);
|
program.setUniformBlockBinding("_FlwFrameUniforms", 0);
|
||||||
|
program.setUniformBlockBinding("_FlwFogUniforms", 1);
|
||||||
})
|
})
|
||||||
.harness(sources);
|
.harness(sources);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,85 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.compile.component;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
|
||||||
import java.util.Collection;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.jozufozu.flywheel.backend.compile.core.SourceLoader;
|
|
||||||
import com.jozufozu.flywheel.backend.glsl.SourceComponent;
|
|
||||||
import com.jozufozu.flywheel.backend.glsl.SourceFile;
|
|
||||||
import com.jozufozu.flywheel.backend.glsl.generate.GlslBuilder;
|
|
||||||
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
public class UniformComponent implements SourceComponent {
|
|
||||||
private final ResourceLocation name;
|
|
||||||
private final ImmutableList<SourceFile> uniformShaders;
|
|
||||||
|
|
||||||
public static Builder builder(ResourceLocation uniforms) {
|
|
||||||
return new Builder(uniforms);
|
|
||||||
}
|
|
||||||
|
|
||||||
private UniformComponent(ResourceLocation name, ImmutableList<SourceFile> uniformShaders) {
|
|
||||||
this.name = name;
|
|
||||||
this.uniformShaders = uniformShaders;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Collection<? extends SourceComponent> included() {
|
|
||||||
return uniformShaders;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public String source() {
|
|
||||||
var builder = new GlslBuilder();
|
|
||||||
|
|
||||||
builder.uniformBlock()
|
|
||||||
.layout("std140")
|
|
||||||
.name("FlwUniforms")
|
|
||||||
.member("FlywheelUniforms", "flywheel");
|
|
||||||
|
|
||||||
builder.blankLine();
|
|
||||||
|
|
||||||
return builder.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation name() {
|
|
||||||
return name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Builder {
|
|
||||||
private final ResourceLocation name;
|
|
||||||
private final List<ResourceLocation> uniformShaders = new ArrayList<>();
|
|
||||||
|
|
||||||
public Builder(ResourceLocation name) {
|
|
||||||
this.name = name;
|
|
||||||
}
|
|
||||||
|
|
||||||
public Builder sources(List<ResourceLocation> sources) {
|
|
||||||
this.uniformShaders.addAll(sources);
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
|
|
||||||
public UniformComponent build(SourceLoader sources) {
|
|
||||||
var out = ImmutableList.<SourceFile>builder();
|
|
||||||
|
|
||||||
boolean errored = false;
|
|
||||||
for (ResourceLocation uniformShader : uniformShaders) {
|
|
||||||
SourceFile sourceFile = sources.find(uniformShader);
|
|
||||||
if (sourceFile != null) {
|
|
||||||
out.add(sourceFile);
|
|
||||||
} else {
|
|
||||||
errored = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (errored) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return new UniformComponent(name, out.build());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,129 +0,0 @@
|
||||||
package com.jozufozu.flywheel.backend.engine;
|
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import java.util.Set;
|
|
||||||
|
|
||||||
import org.lwjgl.opengl.GL32;
|
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
|
||||||
import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent;
|
|
||||||
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
|
|
||||||
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
|
||||||
import com.jozufozu.flywheel.lib.math.MoreMath;
|
|
||||||
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
|
||||||
|
|
||||||
public class UniformBuffer {
|
|
||||||
// private static final int OFFSET_ALIGNMENT = GL32.glGetInteger(GL32.GL_UNIFORM_BUFFER_OFFSET_ALIGNMENT);
|
|
||||||
// private static final int MAX_SIZE = GL32.glGetInteger(GL32.GL_MAX_UNIFORM_BLOCK_SIZE);
|
|
||||||
// private static final int MAX_BINDINGS = GL32.glGetInteger(GL32.GL_MAX_UNIFORM_BUFFER_BINDINGS);
|
|
||||||
// private static final boolean PO2_ALIGNMENT = Mth.isPowerOfTwo(OFFSET_ALIGNMENT);
|
|
||||||
|
|
||||||
private static UniformBuffer instance;
|
|
||||||
|
|
||||||
private final GlBuffer buffer;
|
|
||||||
private final ProviderSet providerSet;
|
|
||||||
|
|
||||||
private UniformBuffer() {
|
|
||||||
buffer = new GlBuffer();
|
|
||||||
providerSet = new ProviderSet(ShaderUniforms.REGISTRY.getAll());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static UniformBuffer get() {
|
|
||||||
if (instance == null) {
|
|
||||||
instance = new UniformBuffer();
|
|
||||||
}
|
|
||||||
return instance;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void sync() {
|
|
||||||
if (providerSet.pollUpdates()) {
|
|
||||||
buffer.upload(providerSet.data);
|
|
||||||
}
|
|
||||||
|
|
||||||
GL32.glBindBufferRange(GL32.GL_UNIFORM_BUFFER, 0, buffer.handle(), 0, providerSet.data.size());
|
|
||||||
}
|
|
||||||
|
|
||||||
private void delete() {
|
|
||||||
providerSet.delete();
|
|
||||||
buffer.delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void onReloadLevelRenderer(ReloadLevelRendererEvent event) {
|
|
||||||
if (instance != null) {
|
|
||||||
instance.delete();
|
|
||||||
instance = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// // https://stackoverflow.com/questions/3407012/rounding-up-to-the-nearest-multiple-of-a-number
|
|
||||||
// private static int alignUniformBuffer(int numToRound) {
|
|
||||||
// if (PO2_ALIGNMENT) {
|
|
||||||
// return (numToRound + OFFSET_ALIGNMENT - 1) & -OFFSET_ALIGNMENT;
|
|
||||||
// } else {
|
|
||||||
// return ((numToRound + OFFSET_ALIGNMENT - 1) / OFFSET_ALIGNMENT) * OFFSET_ALIGNMENT;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
private static class LiveProvider {
|
|
||||||
private final ShaderUniforms shaderUniforms;
|
|
||||||
private final int offset;
|
|
||||||
private final int size;
|
|
||||||
private ShaderUniforms.Provider provider;
|
|
||||||
|
|
||||||
private LiveProvider(ShaderUniforms shaderUniforms, int offset, int size) {
|
|
||||||
this.shaderUniforms = shaderUniforms;
|
|
||||||
this.offset = offset;
|
|
||||||
this.size = size;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updatePtr(MemoryBlock bufferBase) {
|
|
||||||
if (provider != null) {
|
|
||||||
provider.delete();
|
|
||||||
}
|
|
||||||
provider = shaderUniforms.activate(bufferBase.ptr() + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean maybePoll() {
|
|
||||||
return provider != null && provider.poll();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static class ProviderSet {
|
|
||||||
private final List<LiveProvider> allocatedProviders;
|
|
||||||
|
|
||||||
private final MemoryBlock data;
|
|
||||||
|
|
||||||
private ProviderSet(final Set<ShaderUniforms> providers) {
|
|
||||||
var builder = ImmutableList.<LiveProvider>builder();
|
|
||||||
int totalBytes = 0;
|
|
||||||
for (ShaderUniforms provider : providers) {
|
|
||||||
int size = MoreMath.align16(provider.byteSize());
|
|
||||||
|
|
||||||
builder.add(new LiveProvider(provider, totalBytes, size));
|
|
||||||
|
|
||||||
totalBytes += size;
|
|
||||||
}
|
|
||||||
|
|
||||||
allocatedProviders = builder.build();
|
|
||||||
|
|
||||||
data = MemoryBlock.mallocTracked(totalBytes);
|
|
||||||
|
|
||||||
for (LiveProvider p : allocatedProviders) {
|
|
||||||
p.updatePtr(data);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean pollUpdates() {
|
|
||||||
boolean changed = false;
|
|
||||||
for (LiveProvider p : allocatedProviders) {
|
|
||||||
changed |= p.maybePoll();
|
|
||||||
}
|
|
||||||
return changed;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void delete() {
|
|
||||||
allocatedProviders.forEach(p -> p.provider.delete());
|
|
||||||
data.free();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -24,7 +24,7 @@ import com.jozufozu.flywheel.api.model.Mesh;
|
||||||
import com.jozufozu.flywheel.api.model.Model;
|
import com.jozufozu.flywheel.api.model.Model;
|
||||||
import com.jozufozu.flywheel.backend.compile.IndirectPrograms;
|
import com.jozufozu.flywheel.backend.compile.IndirectPrograms;
|
||||||
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
|
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
|
||||||
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
|
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
||||||
import com.jozufozu.flywheel.backend.gl.Driver;
|
import com.jozufozu.flywheel.backend.gl.Driver;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlCompat;
|
import com.jozufozu.flywheel.backend.gl.GlCompat;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
||||||
|
@ -100,7 +100,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UniformBuffer.get().sync();
|
Uniforms.bindFrame();
|
||||||
cullProgram.bind();
|
cullProgram.bind();
|
||||||
buffers.bindForCompute();
|
buffers.bindForCompute();
|
||||||
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
|
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
|
||||||
|
@ -184,7 +184,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
UniformBuffer.get().sync();
|
Uniforms.bindForDraw();
|
||||||
drawProgram.bind();
|
drawProgram.bind();
|
||||||
meshPool.bindForDraw();
|
meshPool.bindForDraw();
|
||||||
buffers.bindForDraw();
|
buffers.bindForDraw();
|
||||||
|
@ -204,8 +204,7 @@ public class IndirectCullingGroup<I extends Instance> {
|
||||||
|
|
||||||
program.bind();
|
program.bind();
|
||||||
|
|
||||||
UniformBuffer.get()
|
Uniforms.bindForDraw();
|
||||||
.sync();
|
|
||||||
meshPool.bindForDraw();
|
meshPool.bindForDraw();
|
||||||
buffers.bindForCrumbling();
|
buffers.bindForCrumbling();
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,7 @@ import com.jozufozu.flywheel.backend.engine.AbstractEngine;
|
||||||
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
||||||
import com.jozufozu.flywheel.backend.engine.InstancerStorage;
|
import com.jozufozu.flywheel.backend.engine.InstancerStorage;
|
||||||
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
|
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
|
||||||
|
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
||||||
import com.jozufozu.flywheel.lib.task.Flag;
|
import com.jozufozu.flywheel.lib.task.Flag;
|
||||||
|
@ -39,8 +40,9 @@ public class IndirectEngine extends AbstractEngine {
|
||||||
return SyncedPlan.of(this::flushDrawManager);
|
return SyncedPlan.of(this::flushDrawManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void flushDrawManager() {
|
private void flushDrawManager(RenderContext ctx) {
|
||||||
try (var state = GlStateTracker.getRestoreState()) {
|
try (var state = GlStateTracker.getRestoreState()) {
|
||||||
|
Uniforms.updateContext(ctx);
|
||||||
drawManager.flush();
|
drawManager.flush();
|
||||||
}
|
}
|
||||||
flushFlag.raise();
|
flushFlag.raise();
|
||||||
|
|
|
@ -13,7 +13,7 @@ import com.jozufozu.flywheel.backend.compile.InstancingPrograms;
|
||||||
import com.jozufozu.flywheel.backend.engine.CommonCrumbling;
|
import com.jozufozu.flywheel.backend.engine.CommonCrumbling;
|
||||||
import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl;
|
import com.jozufozu.flywheel.backend.engine.InstanceHandleImpl;
|
||||||
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
|
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
|
||||||
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
|
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||||
import com.jozufozu.flywheel.lib.context.Contexts;
|
import com.jozufozu.flywheel.lib.context.Contexts;
|
||||||
import com.jozufozu.flywheel.lib.material.SimpleMaterial;
|
import com.jozufozu.flywheel.lib.material.SimpleMaterial;
|
||||||
|
@ -51,7 +51,7 @@ public class InstancedCrumbling {
|
||||||
var program = programs.get(shader.instanceType(), Contexts.CRUMBLING);
|
var program = programs.get(shader.instanceType(), Contexts.CRUMBLING);
|
||||||
program.bind();
|
program.bind();
|
||||||
|
|
||||||
UniformBuffer.get().sync();
|
Uniforms.bindForDraw();
|
||||||
InstancingEngine.uploadMaterialUniform(program, crumblingMaterial);
|
InstancingEngine.uploadMaterialUniform(program, crumblingMaterial);
|
||||||
|
|
||||||
for (Int2ObjectMap.Entry<List<Runnable>> progressEntry : byProgress.int2ObjectEntrySet()) {
|
for (Int2ObjectMap.Entry<List<Runnable>> progressEntry : byProgress.int2ObjectEntrySet()) {
|
||||||
|
|
|
@ -16,7 +16,7 @@ import com.jozufozu.flywheel.backend.engine.AbstractInstancer;
|
||||||
import com.jozufozu.flywheel.backend.engine.InstancerStorage;
|
import com.jozufozu.flywheel.backend.engine.InstancerStorage;
|
||||||
import com.jozufozu.flywheel.backend.engine.MaterialEncoder;
|
import com.jozufozu.flywheel.backend.engine.MaterialEncoder;
|
||||||
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
|
import com.jozufozu.flywheel.backend.engine.MaterialRenderState;
|
||||||
import com.jozufozu.flywheel.backend.engine.UniformBuffer;
|
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||||
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
import com.jozufozu.flywheel.backend.gl.GlTextureUnit;
|
||||||
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
import com.jozufozu.flywheel.backend.gl.shader.GlProgram;
|
||||||
|
@ -46,8 +46,9 @@ public class InstancingEngine extends AbstractEngine {
|
||||||
return SyncedPlan.of(this::flushDrawManager);
|
return SyncedPlan.of(this::flushDrawManager);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void flushDrawManager() {
|
private void flushDrawManager(RenderContext ctx) {
|
||||||
try (var restoreState = GlStateTracker.getRestoreState()) {
|
try (var restoreState = GlStateTracker.getRestoreState()) {
|
||||||
|
Uniforms.updateContext(ctx);
|
||||||
drawManager.flush();
|
drawManager.flush();
|
||||||
}
|
}
|
||||||
flushFlag.raise();
|
flushFlag.raise();
|
||||||
|
@ -118,7 +119,7 @@ public class InstancingEngine extends AbstractEngine {
|
||||||
var program = programs.get(shader.instanceType(), Contexts.DEFAULT);
|
var program = programs.get(shader.instanceType(), Contexts.DEFAULT);
|
||||||
program.bind();
|
program.bind();
|
||||||
|
|
||||||
UniformBuffer.get().sync();
|
Uniforms.bindForDraw();
|
||||||
uploadMaterialUniform(program, shader.material());
|
uploadMaterialUniform(program, shader.material());
|
||||||
|
|
||||||
MaterialRenderState.setup(shader.material());
|
MaterialRenderState.setup(shader.material());
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||||
|
|
||||||
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
|
import com.mojang.blaze3d.systems.RenderSystem;
|
||||||
|
|
||||||
|
public class FogUniforms implements UniformProvider {
|
||||||
|
public static final int SIZE = 28;
|
||||||
|
|
||||||
|
public int byteSize() {
|
||||||
|
return SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(long ptr) {
|
||||||
|
var color = RenderSystem.getShaderFogColor();
|
||||||
|
|
||||||
|
MemoryUtil.memPutFloat(ptr, color[0]);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 4, color[1]);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 8, color[2]);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 12, color[3]);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 16, RenderSystem.getShaderFogStart());
|
||||||
|
MemoryUtil.memPutFloat(ptr + 20, RenderSystem.getShaderFogEnd());
|
||||||
|
MemoryUtil.memPutInt(ptr + 24, RenderSystem.getShaderFogShape()
|
||||||
|
.getIndex());
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,61 @@
|
||||||
|
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||||
|
|
||||||
|
import org.joml.Matrix4f;
|
||||||
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||||
|
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
|
||||||
|
import com.jozufozu.flywheel.lib.math.MatrixMath;
|
||||||
|
|
||||||
|
import net.minecraft.core.Vec3i;
|
||||||
|
import net.minecraft.world.phys.Vec3;
|
||||||
|
|
||||||
|
public class FrameUniforms implements UniformProvider {
|
||||||
|
public static final int SIZE = 192;
|
||||||
|
|
||||||
|
private RenderContext context;
|
||||||
|
|
||||||
|
public int byteSize() {
|
||||||
|
return SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
private final Matrix4f viewProjection = new Matrix4f();
|
||||||
|
|
||||||
|
public void setContext(RenderContext context) {
|
||||||
|
this.context = context;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void write(long ptr) {
|
||||||
|
Vec3i renderOrigin = VisualizationManager.getOrThrow(context.level())
|
||||||
|
.getRenderOrigin();
|
||||||
|
Vec3 camera = context.camera()
|
||||||
|
.getPosition();
|
||||||
|
|
||||||
|
var camX = (float) (camera.x - renderOrigin.getX());
|
||||||
|
var camY = (float) (camera.y - renderOrigin.getY());
|
||||||
|
var camZ = (float) (camera.z - renderOrigin.getZ());
|
||||||
|
|
||||||
|
viewProjection.set(context.viewProjection());
|
||||||
|
viewProjection.translate(-camX, -camY, -camZ);
|
||||||
|
|
||||||
|
MatrixMath.writeUnsafe(viewProjection, ptr);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 64, camX);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 68, camY);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 72, camZ);
|
||||||
|
MemoryUtil.memPutFloat(ptr + 76, 0f); // vec4 alignment
|
||||||
|
MemoryUtil.memPutInt(ptr + 80, getConstantAmbientLightFlag(context));
|
||||||
|
|
||||||
|
if (!Uniforms.frustumPaused || Uniforms.frustumCapture) {
|
||||||
|
MatrixMath.writePackedFrustumPlanes(ptr + 96, viewProjection);
|
||||||
|
Uniforms.frustumCapture = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getConstantAmbientLightFlag(RenderContext context) {
|
||||||
|
var constantAmbientLight = context.level()
|
||||||
|
.effects()
|
||||||
|
.constantAmbientLight();
|
||||||
|
return constantAmbientLight ? 1 : 0;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,38 @@
|
||||||
|
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||||
|
|
||||||
|
import org.lwjgl.opengl.GL32;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBuffer;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.buffer.GlBufferUsage;
|
||||||
|
import com.jozufozu.flywheel.lib.memory.MemoryBlock;
|
||||||
|
|
||||||
|
public class UniformBuffer<T extends UniformProvider> {
|
||||||
|
// private static final int MAX_SIZE = GL32.glGetInteger(GL32.GL_MAX_UNIFORM_BLOCK_SIZE);
|
||||||
|
|
||||||
|
private final int index;
|
||||||
|
private final GlBuffer buffer;
|
||||||
|
public final T provider;
|
||||||
|
private final MemoryBlock data;
|
||||||
|
|
||||||
|
public UniformBuffer(int index, T provider) {
|
||||||
|
this.index = index;
|
||||||
|
this.buffer = new GlBuffer(GlBufferUsage.DYNAMIC_DRAW);
|
||||||
|
this.provider = provider;
|
||||||
|
|
||||||
|
this.data = MemoryBlock.mallocTracked(provider.byteSize());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void update() {
|
||||||
|
provider.write(data.ptr());
|
||||||
|
buffer.upload(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void bind() {
|
||||||
|
GL32.glBindBufferRange(GL32.GL_UNIFORM_BUFFER, index, buffer.handle(), 0, data.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete() {
|
||||||
|
data.free();
|
||||||
|
buffer.delete();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,7 @@
|
||||||
|
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||||
|
|
||||||
|
public interface UniformProvider {
|
||||||
|
void write(long ptr);
|
||||||
|
|
||||||
|
int byteSize();
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
package com.jozufozu.flywheel.backend.engine.uniform;
|
||||||
|
|
||||||
|
import com.jozufozu.flywheel.api.event.ReloadLevelRendererEvent;
|
||||||
|
import com.jozufozu.flywheel.api.event.RenderContext;
|
||||||
|
|
||||||
|
public class Uniforms {
|
||||||
|
public static boolean frustumPaused = false;
|
||||||
|
public static boolean frustumCapture = false;
|
||||||
|
private static UniformBuffer<FrameUniforms> frame;
|
||||||
|
private static UniformBuffer<FogUniforms> fog;
|
||||||
|
|
||||||
|
public static UniformBuffer<FrameUniforms> frame() {
|
||||||
|
if (frame == null) {
|
||||||
|
frame = new UniformBuffer<>(0, new FrameUniforms());
|
||||||
|
}
|
||||||
|
return frame;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static UniformBuffer<FogUniforms> fog() {
|
||||||
|
if (fog == null) {
|
||||||
|
fog = new UniformBuffer<>(1, new FogUniforms());
|
||||||
|
}
|
||||||
|
return fog;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void bindForDraw() {
|
||||||
|
bindFrame();
|
||||||
|
bindFog();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void bindFog() {
|
||||||
|
if (fog != null) {
|
||||||
|
fog.bind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void bindFrame() {
|
||||||
|
if (frame != null) {
|
||||||
|
frame.bind();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void updateContext(RenderContext ctx) {
|
||||||
|
var ubo = frame();
|
||||||
|
ubo.provider.setContext(ctx);
|
||||||
|
ubo.update();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void onReloadLevelRenderer(ReloadLevelRendererEvent event) {
|
||||||
|
if (frame != null) {
|
||||||
|
frame.delete();
|
||||||
|
frame = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fog != null) {
|
||||||
|
fog.delete();
|
||||||
|
fog = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,7 +4,7 @@ import java.util.function.BiConsumer;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.backend.Backend;
|
import com.jozufozu.flywheel.api.backend.Backend;
|
||||||
import com.jozufozu.flywheel.api.backend.BackendManager;
|
import com.jozufozu.flywheel.api.backend.BackendManager;
|
||||||
import com.jozufozu.flywheel.lib.uniform.FlwShaderUniforms;
|
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
||||||
import com.mojang.brigadier.Command;
|
import com.mojang.brigadier.Command;
|
||||||
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
import com.mojang.brigadier.arguments.IntegerArgumentType;
|
||||||
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
import com.mojang.brigadier.builder.LiteralArgumentBuilder;
|
||||||
|
@ -135,18 +135,18 @@ public class FlwCommands {
|
||||||
command.then(Commands.literal("debugFrustum")
|
command.then(Commands.literal("debugFrustum")
|
||||||
.then(Commands.literal("pause")
|
.then(Commands.literal("pause")
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
FlwShaderUniforms.frustumPaused = true;
|
Uniforms.frustumPaused = true;
|
||||||
return 1;
|
return 1;
|
||||||
}))
|
}))
|
||||||
.then(Commands.literal("unpause")
|
.then(Commands.literal("unpause")
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
FlwShaderUniforms.frustumPaused = false;
|
Uniforms.frustumPaused = false;
|
||||||
return 1;
|
return 1;
|
||||||
}))
|
}))
|
||||||
.then(Commands.literal("capture")
|
.then(Commands.literal("capture")
|
||||||
.executes(context -> {
|
.executes(context -> {
|
||||||
FlwShaderUniforms.frustumPaused = true;
|
Uniforms.frustumPaused = true;
|
||||||
FlwShaderUniforms.frustumCapture = true;
|
Uniforms.frustumCapture = true;
|
||||||
return 1;
|
return 1;
|
||||||
})));
|
})));
|
||||||
|
|
||||||
|
|
|
@ -6,14 +6,12 @@ import java.util.Set;
|
||||||
import org.jetbrains.annotations.Unmodifiable;
|
import org.jetbrains.annotations.Unmodifiable;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.api.registry.Registry;
|
import com.jozufozu.flywheel.api.registry.Registry;
|
||||||
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
|
|
||||||
|
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
import it.unimi.dsi.fastutil.objects.ObjectArrayList;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectList;
|
import it.unimi.dsi.fastutil.objects.ObjectList;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
import it.unimi.dsi.fastutil.objects.ObjectOpenHashSet;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
import it.unimi.dsi.fastutil.objects.ObjectSet;
|
||||||
import it.unimi.dsi.fastutil.objects.ObjectSets;
|
import it.unimi.dsi.fastutil.objects.ObjectSets;
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
|
|
||||||
public class RegistryImpl<T> implements Registry<T> {
|
public class RegistryImpl<T> implements Registry<T> {
|
||||||
private static final ObjectList<RegistryImpl<?>> ALL = new ObjectArrayList<>();
|
private static final ObjectList<RegistryImpl<?>> ALL = new ObjectArrayList<>();
|
||||||
|
@ -31,20 +29,6 @@ public class RegistryImpl<T> implements Registry<T> {
|
||||||
return new RegistryImpl<>();
|
return new RegistryImpl<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends ShaderUniforms> Registry<T> createForShaderUniforms() {
|
|
||||||
return new RegistryImpl<>() {
|
|
||||||
private final ObjectSet<ResourceLocation> files = new ObjectOpenHashSet<>();
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void register(T object) {
|
|
||||||
if (!files.add(object.uniformShader())) {
|
|
||||||
throw new IllegalArgumentException();
|
|
||||||
}
|
|
||||||
super.register(object);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void register(T object) {
|
public void register(T object) {
|
||||||
if (frozen) {
|
if (frozen) {
|
||||||
|
|
|
@ -1,134 +0,0 @@
|
||||||
package com.jozufozu.flywheel.lib.uniform;
|
|
||||||
|
|
||||||
import java.util.function.Consumer;
|
|
||||||
|
|
||||||
import org.joml.Matrix4f;
|
|
||||||
import org.lwjgl.system.MemoryUtil;
|
|
||||||
|
|
||||||
import com.jozufozu.flywheel.Flywheel;
|
|
||||||
import com.jozufozu.flywheel.api.event.BeginFrameEvent;
|
|
||||||
import com.jozufozu.flywheel.api.event.RenderContext;
|
|
||||||
import com.jozufozu.flywheel.api.uniform.ShaderUniforms;
|
|
||||||
import com.jozufozu.flywheel.api.visualization.VisualizationManager;
|
|
||||||
import com.jozufozu.flywheel.lib.math.MatrixMath;
|
|
||||||
import com.mojang.blaze3d.systems.RenderSystem;
|
|
||||||
|
|
||||||
import net.minecraft.core.Vec3i;
|
|
||||||
import net.minecraft.resources.ResourceLocation;
|
|
||||||
import net.minecraft.world.phys.Vec3;
|
|
||||||
import net.minecraftforge.common.MinecraftForge;
|
|
||||||
|
|
||||||
public class FlwShaderUniforms implements ShaderUniforms {
|
|
||||||
public static final FlwShaderUniforms INSTANCE = ShaderUniforms.REGISTRY.registerAndGet(new FlwShaderUniforms());
|
|
||||||
|
|
||||||
public static final ResourceLocation FILE = Flywheel.rl("uniform/flywheel.glsl");
|
|
||||||
public static final int SIZE = 224;
|
|
||||||
|
|
||||||
public static boolean frustumPaused = false;
|
|
||||||
public static boolean frustumCapture = false;
|
|
||||||
public static boolean fogUpdate = true;
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public int byteSize() {
|
|
||||||
return SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public ResourceLocation uniformShader() {
|
|
||||||
return FILE;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public Provider activate(long ptr) {
|
|
||||||
return new Active(ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static class Active implements Provider, Consumer<BeginFrameEvent> {
|
|
||||||
private final long ptr;
|
|
||||||
|
|
||||||
private boolean dirty;
|
|
||||||
|
|
||||||
private final Matrix4f viewProjection = new Matrix4f();
|
|
||||||
|
|
||||||
public Active(long ptr) {
|
|
||||||
this.ptr = ptr;
|
|
||||||
MinecraftForge.EVENT_BUS.addListener(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void delete() {
|
|
||||||
MinecraftForge.EVENT_BUS.unregister(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public boolean poll() {
|
|
||||||
boolean updated = maybeUpdateFog();
|
|
||||||
updated |= dirty;
|
|
||||||
dirty = false;
|
|
||||||
return updated;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void accept(BeginFrameEvent event) {
|
|
||||||
if (ptr == MemoryUtil.NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
RenderContext context = event.getContext();
|
|
||||||
|
|
||||||
Vec3i renderOrigin = VisualizationManager.getOrThrow(context.level())
|
|
||||||
.getRenderOrigin();
|
|
||||||
Vec3 camera = context.camera()
|
|
||||||
.getPosition();
|
|
||||||
|
|
||||||
var camX = (float) (camera.x - renderOrigin.getX());
|
|
||||||
var camY = (float) (camera.y - renderOrigin.getY());
|
|
||||||
var camZ = (float) (camera.z - renderOrigin.getZ());
|
|
||||||
|
|
||||||
viewProjection.set(context.viewProjection());
|
|
||||||
viewProjection.translate(-camX, -camY, -camZ);
|
|
||||||
|
|
||||||
MatrixMath.writeUnsafe(viewProjection, ptr + 32);
|
|
||||||
MemoryUtil.memPutFloat(ptr + 96, camX);
|
|
||||||
MemoryUtil.memPutFloat(ptr + 100, camY);
|
|
||||||
MemoryUtil.memPutFloat(ptr + 104, camZ);
|
|
||||||
MemoryUtil.memPutFloat(ptr + 108, 0f); // vec4 alignment
|
|
||||||
MemoryUtil.memPutInt(ptr + 112, getConstantAmbientLightFlag(context));
|
|
||||||
|
|
||||||
if (!frustumPaused || frustumCapture) {
|
|
||||||
MatrixMath.writePackedFrustumPlanes(ptr + 128, viewProjection);
|
|
||||||
frustumCapture = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
dirty = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static int getConstantAmbientLightFlag(RenderContext context) {
|
|
||||||
var constantAmbientLight = context.level()
|
|
||||||
.effects()
|
|
||||||
.constantAmbientLight();
|
|
||||||
return constantAmbientLight ? 1 : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean maybeUpdateFog() {
|
|
||||||
if (!fogUpdate || ptr == MemoryUtil.NULL) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
var color = RenderSystem.getShaderFogColor();
|
|
||||||
|
|
||||||
MemoryUtil.memPutFloat(ptr, color[0]);
|
|
||||||
MemoryUtil.memPutFloat(ptr + 4, color[1]);
|
|
||||||
MemoryUtil.memPutFloat(ptr + 8, color[2]);
|
|
||||||
MemoryUtil.memPutFloat(ptr + 12, color[3]);
|
|
||||||
MemoryUtil.memPutFloat(ptr + 16, RenderSystem.getShaderFogStart());
|
|
||||||
MemoryUtil.memPutFloat(ptr + 20, RenderSystem.getShaderFogEnd());
|
|
||||||
MemoryUtil.memPutInt(ptr + 24, RenderSystem.getShaderFogShape()
|
|
||||||
.getIndex());
|
|
||||||
|
|
||||||
fogUpdate = false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,7 +6,8 @@ import org.spongepowered.asm.mixin.injection.At;
|
||||||
import org.spongepowered.asm.mixin.injection.Inject;
|
import org.spongepowered.asm.mixin.injection.Inject;
|
||||||
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
|
||||||
|
|
||||||
import com.jozufozu.flywheel.lib.uniform.FlwShaderUniforms;
|
import com.jozufozu.flywheel.backend.engine.uniform.Uniforms;
|
||||||
|
import com.jozufozu.flywheel.backend.gl.GlStateTracker;
|
||||||
|
|
||||||
import net.minecraft.client.renderer.FogRenderer;
|
import net.minecraft.client.renderer.FogRenderer;
|
||||||
|
|
||||||
|
@ -14,7 +15,10 @@ import net.minecraft.client.renderer.FogRenderer;
|
||||||
abstract class FogUpdateMixin {
|
abstract class FogUpdateMixin {
|
||||||
@Unique
|
@Unique
|
||||||
private static void flywheel$updateFog() {
|
private static void flywheel$updateFog() {
|
||||||
FlwShaderUniforms.fogUpdate = true;
|
try (var restoreState = GlStateTracker.getRestoreState()) {
|
||||||
|
Uniforms.fog()
|
||||||
|
.update();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Inject(method = "setupNoFog()V", at = @At("RETURN"))
|
@Inject(method = "setupNoFog()V", at = @At("RETURN"))
|
||||||
|
|
|
@ -8,5 +8,5 @@ vec4 linearFog(vec4 color, float distance, float fogStart, float fogEnd, vec4 fo
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 flw_fogFilter(vec4 color) {
|
vec4 flw_fogFilter(vec4 color) {
|
||||||
return linearFog(color, flw_distance, flywheel.fogRange.x, flywheel.fogRange.y, flywheel.fogColor);
|
return linearFog(color, flw_distance, flw_fogRange.x, flw_fogRange.y, flw_fogColor);
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,5 +9,5 @@ vec4 linearFogFade(vec4 color, float distance, float fogStart, float fogEnd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
vec4 flw_fogFilter(vec4 color) {
|
vec4 flw_fogFilter(vec4 color) {
|
||||||
return linearFogFade(color, flw_distance, flywheel.fogRange.x, flywheel.fogRange.y);
|
return linearFogFade(color, flw_distance, flw_fogRange.x, flw_fogRange.y);
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ void _flw_main() {
|
||||||
|
|
||||||
if (flw_fragDiffuse) {
|
if (flw_fragDiffuse) {
|
||||||
float diffuseFactor;
|
float diffuseFactor;
|
||||||
if (flywheel.constantAmbientLight == 1) {
|
if (flw_constantAmbientLight == 1) {
|
||||||
diffuseFactor = diffuseNether(flw_vertexNormal);
|
diffuseFactor = diffuseNether(flw_vertexNormal);
|
||||||
} else {
|
} else {
|
||||||
diffuseFactor = diffuse(flw_vertexNormal);
|
diffuseFactor = diffuse(flw_vertexNormal);
|
||||||
|
|
|
@ -15,6 +15,6 @@ void _flw_main(in FlwInstance instance) {
|
||||||
|
|
||||||
_flw_vertexDiffuse = uint(flw_vertexDiffuse);
|
_flw_vertexDiffuse = uint(flw_vertexDiffuse);
|
||||||
|
|
||||||
flw_distance = fogDistance(flw_vertexPos.xyz, flywheel.cameraPos.xyz, flywheel.fogShape);
|
flw_distance = fogDistance(flw_vertexPos.xyz, flw_cameraPos.xyz, flw_fogShape);
|
||||||
gl_Position = flywheel.viewProjection * flw_vertexPos;
|
gl_Position = flw_viewProjection * flw_vertexPos;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#include "flywheel:internal/material.glsl"
|
#include "flywheel:internal/material.glsl"
|
||||||
|
#include "flywheel:internal/uniforms/frame.glsl"
|
||||||
|
#include "flywheel:internal/uniforms/fog.glsl"
|
||||||
|
|
||||||
in vec4 flw_vertexPos;
|
in vec4 flw_vertexPos;
|
||||||
in vec4 flw_vertexColor;
|
in vec4 flw_vertexColor;
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#include "flywheel:internal/material.glsl"
|
#include "flywheel:internal/material.glsl"
|
||||||
|
#include "flywheel:internal/uniforms/frame.glsl"
|
||||||
|
#include "flywheel:internal/uniforms/fog.glsl"
|
||||||
|
|
||||||
// TODO: can we combine some of these internally to use fewer in/out slots?
|
// TODO: can we combine some of these internally to use fewer in/out slots?
|
||||||
out vec4 flw_vertexPos;
|
out vec4 flw_vertexPos;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#include "flywheel:internal/indirect/buffers.glsl"
|
#include "flywheel:internal/indirect/buffers.glsl"
|
||||||
#include "flywheel:internal/indirect/model_descriptor.glsl"
|
#include "flywheel:internal/indirect/model_descriptor.glsl"
|
||||||
#include "flywheel:internal/indirect/object.glsl"
|
#include "flywheel:internal/indirect/object.glsl"
|
||||||
|
#include "flywheel:internal/uniforms/frame.glsl"
|
||||||
|
|
||||||
layout(local_size_x = _FLW_SUBGROUP_SIZE) in;
|
layout(local_size_x = _FLW_SUBGROUP_SIZE) in;
|
||||||
|
|
||||||
|
@ -23,8 +24,8 @@ layout(std430, binding = _FLW_MODEL_BUFFER_BINDING) restrict buffer ModelBuffer
|
||||||
// com.jozufozu.flywheel.lib.math.MatrixMath.writePackedFrustumPlanes
|
// com.jozufozu.flywheel.lib.math.MatrixMath.writePackedFrustumPlanes
|
||||||
// org.joml.FrustumIntersection.testSphere
|
// org.joml.FrustumIntersection.testSphere
|
||||||
bool _flw_testSphere(vec3 center, float radius) {
|
bool _flw_testSphere(vec3 center, float radius) {
|
||||||
bvec4 xyInside = greaterThanEqual(fma(flywheel.planes.xyX, center.xxxx, fma(flywheel.planes.xyY, center.yyyy, fma(flywheel.planes.xyZ, center.zzzz, flywheel.planes.xyW))), -radius.xxxx);
|
bvec4 xyInside = greaterThanEqual(fma(flw_frustumPlanes.xyX, center.xxxx, fma(flw_frustumPlanes.xyY, center.yyyy, fma(flw_frustumPlanes.xyZ, center.zzzz, flw_frustumPlanes.xyW))), -radius.xxxx);
|
||||||
bvec2 zInside = greaterThanEqual(fma(flywheel.planes.zX, center.xx, fma(flywheel.planes.zY, center.yy, fma(flywheel.planes.zZ, center.zz, flywheel.planes.zW))), -radius.xx);
|
bvec2 zInside = greaterThanEqual(fma(flw_frustumPlanes.zX, center.xx, fma(flw_frustumPlanes.zY, center.yy, fma(flw_frustumPlanes.zZ, center.zz, flw_frustumPlanes.zW))), -radius.xx);
|
||||||
|
|
||||||
return all(xyInside) && all(zInside);
|
return all(xyInside) && all(zInside);
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
layout(std140) uniform _FlwFogUniforms {
|
||||||
|
vec4 flw_fogColor;
|
||||||
|
vec2 flw_fogRange;
|
||||||
|
int flw_fogShape;
|
||||||
|
};
|
|
@ -0,0 +1,17 @@
|
||||||
|
struct FrustumPlanes {
|
||||||
|
vec4 xyX;// <nx.x, px.x, ny.x, py.x>
|
||||||
|
vec4 xyY;// <nx.y, px.y, ny.y, py.y>
|
||||||
|
vec4 xyZ;// <nx.z, px.z, ny.z, py.z>
|
||||||
|
vec4 xyW;// <nx.w, px.w, ny.w, py.w>
|
||||||
|
vec2 zX;// <nz.x, pz.x>
|
||||||
|
vec2 zY;// <nz.y, pz.y>
|
||||||
|
vec2 zZ;// <nz.z, pz.z>
|
||||||
|
vec2 zW;// <nz.w, pz.w>
|
||||||
|
};
|
||||||
|
|
||||||
|
layout(std140) uniform _FlwFrameUniforms {
|
||||||
|
mat4 flw_viewProjection;
|
||||||
|
vec4 flw_cameraPos;
|
||||||
|
int flw_constantAmbientLight;
|
||||||
|
FrustumPlanes flw_frustumPlanes;
|
||||||
|
};
|
|
@ -1,20 +0,0 @@
|
||||||
struct FrustumPlanes {
|
|
||||||
vec4 xyX; // <nx.x, px.x, ny.x, py.x>
|
|
||||||
vec4 xyY; // <nx.y, px.y, ny.y, py.y>
|
|
||||||
vec4 xyZ; // <nx.z, px.z, ny.z, py.z>
|
|
||||||
vec4 xyW; // <nx.w, px.w, ny.w, py.w>
|
|
||||||
vec2 zX; // <nz.x, pz.x>
|
|
||||||
vec2 zY; // <nz.y, pz.y>
|
|
||||||
vec2 zZ; // <nz.z, pz.z>
|
|
||||||
vec2 zW; // <nz.w, pz.w>
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FlywheelUniforms {
|
|
||||||
vec4 fogColor;
|
|
||||||
vec2 fogRange;
|
|
||||||
int fogShape;
|
|
||||||
mat4 viewProjection;
|
|
||||||
vec4 cameraPos;
|
|
||||||
int constantAmbientLight;
|
|
||||||
FrustumPlanes planes;
|
|
||||||
};
|
|
Loading…
Reference in a new issue