Files
Angelica/src/main/java/net/coderbot/iris/shaderpack/ProgramSet.java
T
+4 992644c20f The Mergening (#13)
* ThreadedTessellator -> RenderBlocks instance Tessellator
* Plus a CME workaround until I can figure out why it's happening
* One inject with multiple methods instead of two injects
* Add AF's Tessellator#reset mixin
Fixes screen flashing when chunks are being built
* Thread Saftey
* Make each tesselator use its own ByteBuffer
* Don't make RecyclingList a static variable 🤦
* Add some additions via ITessellatorInstance
* Stop using builtin updateRenderers
* Remove a few unused things in MixinTessellator
* Remove useless casting due to implementing the interface
* Overwrite some more rendering methods to ensure they're not used
* Implement IBlockAccess on WorldSlice
* Currently just proxies to the World... need to get it to use the local cache
* Make WorldSlice use its copied values instead of using the world
* block, meta, and light.  Still need TODO biome
* Finish making WorldSlice thread safe
* Remove last unsafe this.world accesses
* Copy biomeData
* Implement getTileEntity(), and getBiomeGenForCoords()
* Remove unused 1.16+ classes - Biome, Colorizer, and ColorBlender related
* Cache worldHeight instead of asking the provider every time
* Debug Screen updates
* Disable Culling for now (until it works)
* Tessellator Updates
* Use one instance on the main thread, and individual instances on every other thread
* Prevent draw() and buffer.reset() on non singleton instance
* Misc cleanup, maybe better growBuffer?
* Fixing splash screen and GUI issues by excluding SplashProgress from GLStateManager transformer
* Update docs
* Fixing a one line in SodiumWorldRenderer that allows the game setting for the distance at which entities will render. Hope it's not too bad mitch :)
* TileEntites now render
* Less silly transparency
* Removing clamp implementation because I missed the one in mathhelper
* Initial sodium entity smooth lighting
* Fix entity smooth lighting
* Fix lerp uses and use render layers properly (#17)
* Remove some uses of blockstate + patch FluidState
* Fix lerp
* Enable Sodium fluid rendering
* Update FluidRenderer.java
* Rewind buffers when copying
* Fix multidraw
* Force cutout on all non-translucent blocks
* Let vanilla handle render pass state
* Rewrite render layer check to use Forge 1.7 hook
* Fix skylight handling
* Fix flickering
* Clone TEs correctly
* Fixing entityDistMulti (I think)
* Fix TEs rendering on the wrong pass
* Buff max render distance to 32
Pretty useless since the integrated server stalls instantly, but our renderer supports it
* Fix fog
* Fix render distance changes being ignored
* Implement entity culling
* Block face culling
* Re-enable occlusion culling
* Fix x/z coordinate mixup when indexing biome arrays
Partially fixes wrong biome colors, but at chunk edges it's still wrong because
neighboring chunks aren't accessed
* Make a copy of biome data
The old code seemed to work fine but this should be safer
* Make CompatMemoryUtil#memReallocDirect preserve buffer position
LWJGL3's MemoryUtil#memRealloc does this, see its javadoc.
Fixes screen flashing and this error getting printed when indirect buffer grows:
GL_INVALID_OPERATION error generated. Bound draw indirect buffer is not large enough.
* Use biome data of neighboring chunk sections
Fixes wrong colors at chunk edges
* Re-enable fog culling
* Tile entity culling
* Remove some unneeded Sodium code
* Massive code cleanup
* Avoids errors when usin lwjglxdebug
* Bump hodgepodge dep
* Add AngelicaConfig
* Add Mixin to disable MC's builtin checkGLError
* Add configs for iris/sodium
* Iris work
* Move some StateNotifiers to GLStateManager
* Remove some redundant mixins based on sodium/angelica work and rendering state captures
* Add Iris DebugScreenHandler
* rm archaicfix's occlusion renderer and threaded updates
* Implemented Sodium's GUI and a couple of setting fixes (#20)
* Ported Sodium's GUI
* Correct AO
* Fixed Vignette
* Re-enable DirectMemoryAccess
* Adds some code from lwjgl3 in CompatMemoryUtil.java
* Re-add *Unsafe classes
* Remove MixinWorldRenderer
* Add NEID (mixin pr) support
* Only shadow runtime module of antlr4
Reduces jar size by 11 mb
* Update NotFine
* Make LongHashMap actually perform like a hash map
* Options GUI Fixes and some option implementations (#22)
* Correct useNoErrorGLContext option
* Added translucency sorting option
* Implemented Particle Culling
gives real fps boost, however, it's not as big as i thought

* Begin implementing animateOnlyVisibleTextures
* Correct Donation page opening
* Fixed Shift + P
Now it uses NotFine's GUI, but it think that NotFine's GUI should be rewrited for using other config options
* Correct URL's for Linux
* second code cleanup in particle culling
* Fix incorrect TE map population
* Add optional assertMainThread behind `-Dangelica.assertMainThread=true`
* Add back air optimization, but only apply to vanilla air
* Implement more options (#23)
* Combine free regions in GlBufferArena
* Clear global block entity list when initializing renderer
* AF, CompileStubs, and SplashProgress
Remove most of ArchaicFix
* Move a few mixins over to angelica
* Disable if org.lwjgl.util.Debug is set
* Only enable Iris/lwjgl debug callbacks if org.lwjgl.util.Debug is set
* Rewrite Tessellator hacks - now using a ThreadLocal instead of only patching RenderBlocks
* Reenable AF mixins, switch to cached debug var, disable incompatible mixins
* Remove AF deps and a late mixin that was missed
* Add Iris Sodium Compat impl
* Fix Sodium GLProgram to use ResourceLocation instead of Identifier
* Start applying Iris -> Sodium Mixins
* Make NotFine menu open if holding shift
* Fixed Tessellators in production env
* Finish Sodium Fluid Renderer (#24)
* Init and pass Sodium LightPipelines
* Remove registry lookup and refactor WorldUtil
* Hook up lighting pipeline
* Patch fluid velocity
* It's alive! Sodium Fluid Renderer is alive!
* Fix face culling not taking third person camera offset into account
* rewrite ACTEntityRenderer to stop transforming ALL the classes
* use ClassConstantPoolParser in TessellatorTransformer to speed up search for Tessellator references
* use ClassConstantPoolParser in GLStateManagerTransformer to speed up search for class references
* rewrite GLStateManagerTransformer and TessellatorTransformer
* merge GLStateManagerTransfor and TessellatorTransformer into one Transformer
* Fixed smooth lighting rendering
* Iris block_id Mixins & BlockStateIdMap initial impl for 1.7.10
* Fix running with lwjgl debug flag & Cleanup old ShadersMod transformers
* Initialize GLStateManager via Mixins instead of all in the static block
* Clean up chunk load/unload tracking, fix chunks rendering without neighbors sometimes
* Fix occlusion culler not re-running after important uploads

Backport of https://github.com/CaffeineMC/sodium-fabric/pull/755

* Add chunks to queues without going through occlusion culler

Partially reverts the previous chunk tracking commit, because
that logic will reintroduce https://github.com/CaffeineMC/sodium-fabric/issues/605

As long as we only rebuild with neighbors present, we shouldn't
see the visual seams
* Extremely primitive synchronization approach for ISBRH
* Use factory for Spdium menu createElement outputs
This will allow NotFine to use Sodium menu elements and vice versa in a future commit.
* Splash Screen Compat
* Separate remaining NamedState enums
* NotFine but it loads Sodium pages
* Hook up NotFine optimizations
* Hook up some NotFine features
* copy over hud caching code from hodgepodge
* backport glstatemanager mixin
* Track thread that currently owns the GL Context in addition to the main thread.
* First pass over FontRenderer, 1300->1400 FPS on my GPU when showing F3
Done:
 - A batching vertex buffer builder for font output
 - Reduction in drawcalls from 1-3 per character to 1 per font atlas switch
 - Mixin to draw the entire F3 screen in one batch, instead of separate batches per line
TODO:
 - Switch drawing to a VBO
 - Cache string meshes across frames
 - Cache string width calculations used for layouts
 - Multidraw to reduce draw calls even further
* Add JVM flag to bypass GL state caching
* Push/Pop Attrib Hacks -- to be evolved later
* Fix FontRenderer+SplashScreen combo
* HUDCaching tweaks
* Add license
* Jabba Compat, and reset tesselator state even if the chunk render thread blows up
* Initial Xaero's World Map + Minimap Support
* Disable Fastcraft & Optifine if present
* Iris Progress
* Wire up more Iris mixins, informing pipeline stages.  Still not rendering anything visible.
* Don't try to transform the server
* Avoid running biome generator on client in singleplayer
* Call world biome retrieval methods instead of copying array directly (#25)
* Shaders now do something!
* Shadow Pass work
* First shadow pass renders; however it moves all around when moving the camera...
* Second shadow pass not running because it makes everything very very dark instead of just rendering translucents
* Actually use the ShadowRenderer Model View when running the shadow pass...
* Enable Sodium SmoothLightPipeline & Iris useSeparateAo
* Avoid repeatedly copying biome data on each Y level (#27)
* Celestial Rotation fixes
* Water progress
* Uniforms audit
* Lightmap workaround
* PBR compiling, stuck on Normal and Specular textures being added in
* Shaderpack selection "works"; ShaderOptions TODO
* Hud caching angelica (#28)
* Potential hud-caching fix
* Shader Options almost working
** Clicking on everything doesn't yet work, and the visuals are slightly off
* Entity shadows seem to be working
* Move glint fix to Mixin
* Rework mouse handling for ShaderPackConfig
* Stop centering shader options vertically
* Angelica pbr (#31)
* Only use Sodium light pipeline if useSeparateAo is on
Sodium pipeline is still very buggy, so isolate it to Iris-only
for now
* Fix region sorting for translucency
* Open Shaderpack now works on Linux
* RM Shadersmod
* Initial iris scrollbar clicking
* Punt unsupported ISBRHs to the main thread
* Delete the ISBRH lock, shouldn't be needed anymore
* Render GT blocks on main thread
* Require CCC 1.2.0+
* Depend on CCC 1.2
* Fix TESRs not being tracked for blocks rendered on main thread
* Cut down number of runtime dependencies, enable CoreTweaks in dev by default
* Add modern F3 background
* Pull over some hodgepodge mixins


---------

Co-authored-by: makamys <makamys@outlook.com>
Co-authored-by: embeddedt <42941056+embeddedt@users.noreply.github.com>
Co-authored-by: rjnasers <rjnasers@iastate.edu>
Co-authored-by: ah-OOG-ah <75745146+ah-OOG-ah@users.noreply.github.com>
Co-authored-by: Ryan Nasers <ryannasersgig@gmail.com>
Co-authored-by: Rad <radoslaw.ryszka006@gmail.com>
Co-authored-by: Bogdan <64613894+Asek3@users.noreply.github.com>
Co-authored-by: Caedis <Caedis@users.noreply.github.com>
Co-authored-by: jss2a98aj <jss2a98aj@gmail.com>
Co-authored-by: Alexdoru <57050655+Alexdoru@users.noreply.github.com>
Co-authored-by: Raven Szewczyk <git@eigenraven.me>
Co-authored-by: mist475 <70655895+mist475@users.noreply.github.com>
Co-authored-by: Ryan Nasers <42074409+Cardinalstars@users.noreply.github.com>
2023-12-24 21:49:28 -08:00

454 lines
17 KiB
Java

package net.coderbot.iris.shaderpack;
import net.coderbot.iris.Iris;
import net.coderbot.iris.gl.blending.BlendModeOverride;
import net.coderbot.iris.shaderpack.include.AbsolutePackPath;
import net.coderbot.iris.shaderpack.loading.ProgramId;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.function.Function;
public class ProgramSet {
private final PackDirectives packDirectives;
private final ProgramSource shadow;
private final ComputeSource[] shadowCompute;
private final ProgramSource[] shadowcomp;
private final ComputeSource[][] shadowCompCompute;
private final ProgramSource[] prepare;
private final ComputeSource[][] prepareCompute;
private final ProgramSource gbuffersBasic;
private final ProgramSource gbuffersLine;
private final ProgramSource gbuffersBeaconBeam;
private final ProgramSource gbuffersTextured;
private final ProgramSource gbuffersTexturedLit;
private final ProgramSource gbuffersTerrain;
private ProgramSource gbuffersDamagedBlock;
private final ProgramSource gbuffersSkyBasic;
private final ProgramSource gbuffersSkyTextured;
private final ProgramSource gbuffersClouds;
private final ProgramSource gbuffersWeather;
private final ProgramSource gbuffersEntities;
private final ProgramSource gbuffersEntitiesTrans;
private final ProgramSource gbuffersEntitiesGlowing;
private final ProgramSource gbuffersGlint;
private final ProgramSource gbuffersEntityEyes;
private final ProgramSource gbuffersBlock;
private final ProgramSource gbuffersHand;
private final ProgramSource[] deferred;
private final ComputeSource[][] deferredCompute;
private final ProgramSource gbuffersWater;
private final ProgramSource gbuffersHandWater;
private final ProgramSource[] composite;
private final ComputeSource[][] compositeCompute;
private final ProgramSource compositeFinal;
private final ComputeSource[] finalCompute;
private final ShaderPack pack;
public ProgramSet(AbsolutePackPath directory, Function<AbsolutePackPath, String> sourceProvider,
ShaderProperties shaderProperties, ShaderPack pack) {
this.packDirectives = new PackDirectives(PackRenderTargetDirectives.BASELINE_SUPPORTED_RENDER_TARGETS, shaderProperties);
this.pack = pack;
// Note: Ensure that blending is properly overridden during the shadow pass. By default, blending is disabled
// in the shadow pass. Shader packs expect this for colored shadows from stained glass and nether portals
// to work properly.
//
// Note: Enabling blending in the shadow pass results in weird results since translucency sorting happens
// relative to the player camera, not the shadow camera, so we can't rely on chunks being properly
// sorted in the shadow pass.
//
// - https://github.com/IrisShaders/Iris/issues/483
// - https://github.com/IrisShaders/Iris/issues/987
this.shadow = readProgramSource(directory, sourceProvider, "shadow", this, shaderProperties,
BlendModeOverride.OFF);
this.shadowCompute = readComputeArray(directory, sourceProvider, "shadow");
this.shadowcomp = readProgramArray(directory, sourceProvider, "shadowcomp", shaderProperties);
this.shadowCompCompute = new ComputeSource[shadowcomp.length][];
for (int i = 0; i < shadowcomp.length; i++) {
this.shadowCompCompute[i] = readComputeArray(directory, sourceProvider, "shadowcomp" + ((i == 0) ? "" : i));
}
this.prepare = readProgramArray(directory, sourceProvider, "prepare", shaderProperties);
this.prepareCompute = new ComputeSource[prepare.length][];
for (int i = 0; i < prepare.length; i++) {
this.prepareCompute[i] = readComputeArray(directory, sourceProvider, "prepare" + ((i == 0) ? "" : i));
}
this.gbuffersBasic = readProgramSource(directory, sourceProvider, "gbuffers_basic", this, shaderProperties);
this.gbuffersLine = readProgramSource(directory, sourceProvider, "gbuffers_line", this, shaderProperties);
this.gbuffersBeaconBeam = readProgramSource(directory, sourceProvider, "gbuffers_beaconbeam", this, shaderProperties);
this.gbuffersTextured = readProgramSource(directory, sourceProvider, "gbuffers_textured", this, shaderProperties);
this.gbuffersTexturedLit = readProgramSource(directory, sourceProvider, "gbuffers_textured_lit", this, shaderProperties);
this.gbuffersTerrain = readProgramSource(directory, sourceProvider, "gbuffers_terrain", this, shaderProperties);
this.gbuffersDamagedBlock = readProgramSource(directory, sourceProvider, "gbuffers_damagedblock", this, shaderProperties);
this.gbuffersSkyBasic = readProgramSource(directory, sourceProvider, "gbuffers_skybasic", this, shaderProperties);
this.gbuffersSkyTextured = readProgramSource(directory, sourceProvider, "gbuffers_skytextured", this, shaderProperties);
this.gbuffersClouds = readProgramSource(directory, sourceProvider, "gbuffers_clouds", this, shaderProperties);
this.gbuffersWeather = readProgramSource(directory, sourceProvider, "gbuffers_weather", this, shaderProperties);
this.gbuffersEntities = readProgramSource(directory, sourceProvider, "gbuffers_entities", this, shaderProperties);
this.gbuffersEntitiesTrans = readProgramSource(directory, sourceProvider, "gbuffers_entities_translucent", this, shaderProperties);
this.gbuffersEntitiesGlowing = readProgramSource(directory, sourceProvider, "gbuffers_entities_glowing", this, shaderProperties);
this.gbuffersGlint = readProgramSource(directory, sourceProvider, "gbuffers_armor_glint", this, shaderProperties);
this.gbuffersEntityEyes = readProgramSource(directory, sourceProvider, "gbuffers_spidereyes", this, shaderProperties);
this.gbuffersBlock = readProgramSource(directory, sourceProvider, "gbuffers_block", this, shaderProperties);
this.gbuffersHand = readProgramSource(directory, sourceProvider, "gbuffers_hand", this, shaderProperties);
this.deferred = readProgramArray(directory, sourceProvider, "deferred", shaderProperties);
this.deferredCompute = new ComputeSource[deferred.length][];
for (int i = 0; i < deferred.length; i++) {
this.deferredCompute[i] = readComputeArray(directory, sourceProvider, "deferred" + ((i == 0) ? "" : i));
}
this.gbuffersWater = readProgramSource(directory, sourceProvider, "gbuffers_water", this, shaderProperties);
this.gbuffersHandWater = readProgramSource(directory, sourceProvider, "gbuffers_hand_water", this, shaderProperties);
this.composite = readProgramArray(directory, sourceProvider, "composite", shaderProperties);
this.compositeCompute = new ComputeSource[composite.length][];
for (int i = 0; i < deferred.length; i++) {
this.compositeCompute[i] = readComputeArray(directory, sourceProvider, "composite" + ((i == 0) ? "" : i));
}
this.compositeFinal = readProgramSource(directory, sourceProvider, "final", this, shaderProperties);
this.finalCompute = readComputeArray(directory, sourceProvider, "final");
locateDirectives();
if (!gbuffersDamagedBlock.isValid()) {
// Special behavior inherited by OptiFine & Iris from old ShadersMod
// Presumably this was added before DRAWBUFFERS was a thing? Or just a hardcoded hacky fix for some
// shader packs - in any case, Sildurs Vibrant Shaders and other packs rely on it.
first(getGbuffersTerrain(), getGbuffersTexturedLit(), getGbuffersTextured(), getGbuffersBasic()).ifPresent(src -> {
ProgramDirectives overrideDirectives = src.getDirectives().withOverriddenDrawBuffers(new int[] { 0 });
this.gbuffersDamagedBlock = src.withDirectiveOverride(overrideDirectives);
});
}
}
@SafeVarargs
private static <T> Optional<T> first(Optional<T>... candidates) {
for (Optional<T> candidate : candidates) {
if (candidate.isPresent()) {
return candidate;
}
}
return Optional.empty();
}
private ProgramSource[] readProgramArray(AbsolutePackPath directory,
Function<AbsolutePackPath, String> sourceProvider, String name,
ShaderProperties shaderProperties) {
ProgramSource[] programs = new ProgramSource[99];
for (int i = 0; i < programs.length; i++) {
String suffix = i == 0 ? "" : Integer.toString(i);
programs[i] = readProgramSource(directory, sourceProvider, name + suffix, this, shaderProperties);
}
return programs;
}
private ComputeSource[] readComputeArray(AbsolutePackPath directory,
Function<AbsolutePackPath, String> sourceProvider, String name) {
ComputeSource[] programs = new ComputeSource[27];
programs[0] = readComputeSource(directory, sourceProvider, name, this);
for (char c = 'a'; c <= 'z'; ++c) {
String suffix = "_" + c;
programs[c - 96] = readComputeSource(directory, sourceProvider, name + suffix, this);
if (programs[c - 96] == null) {
break;
}
}
return programs;
}
private void locateDirectives() {
List<ProgramSource> programs = new ArrayList<>();
List<ComputeSource> computes = new ArrayList<>();
programs.add(shadow);
programs.addAll(Arrays.asList(shadowcomp));
programs.addAll(Arrays.asList(prepare));
programs.addAll (Arrays.asList(
gbuffersBasic, gbuffersBeaconBeam, gbuffersTextured, gbuffersTexturedLit, gbuffersTerrain,
gbuffersDamagedBlock, gbuffersSkyBasic, gbuffersSkyTextured, gbuffersClouds, gbuffersWeather,
gbuffersEntities, gbuffersEntitiesTrans, gbuffersEntitiesGlowing, gbuffersGlint, gbuffersEntityEyes, gbuffersBlock,
gbuffersHand
));
for (ComputeSource[] computeSources : compositeCompute) {
computes.addAll(Arrays.asList(computeSources));
}
for (ComputeSource[] computeSources : deferredCompute) {
computes.addAll(Arrays.asList(computeSources));
}
for (ComputeSource[] computeSources : prepareCompute) {
computes.addAll(Arrays.asList(computeSources));
}
for (ComputeSource[] computeSources : shadowCompCompute) {
computes.addAll(Arrays.asList(computeSources));
}
Collections.addAll(computes, finalCompute);
Collections.addAll(computes, shadowCompute);
for (ComputeSource source : computes) {
if (source != null) {
source.getSource().map(ConstDirectiveParser::findDirectives).ifPresent(constDirectives -> {
for (ConstDirectiveParser.ConstDirective directive : constDirectives) {
if (directive.getType() == ConstDirectiveParser.Type.IVEC3 && directive.getKey().equals("workGroups")) {
ComputeDirectiveParser.setComputeWorkGroups(source, directive);
} else if (directive.getType() == ConstDirectiveParser.Type.VEC2 && directive.getKey().equals("workGroupsRender")) {
ComputeDirectiveParser.setComputeWorkGroupsRelative(source, directive);
}
}
});
}
}
programs.addAll(Arrays.asList(deferred));
programs.add(gbuffersWater);
programs.add(gbuffersHandWater);
programs.addAll(Arrays.asList(composite));
programs.add(compositeFinal);
DispatchingDirectiveHolder packDirectiveHolder = new DispatchingDirectiveHolder();
packDirectives.acceptDirectivesFrom(packDirectiveHolder);
for (ProgramSource source : programs) {
if (source == null) {
continue;
}
source.getFragmentSource().map(ConstDirectiveParser::findDirectives).ifPresent(directives -> {
for (ConstDirectiveParser.ConstDirective directive : directives) {
packDirectiveHolder.processDirective(directive);
}
});
}
packDirectives.getRenderTargetDirectives().getRenderTargetSettings().forEach((index, settings) ->
Iris.logger.debug("Render target settings for colortex" + index + ": " + settings));
}
public Optional<ProgramSource> getShadow() {
return shadow.requireValid();
}
public ProgramSource[] getShadowComposite() {
return shadowcomp;
}
public ProgramSource[] getPrepare() {
return prepare;
}
public Optional<ProgramSource> getGbuffersBasic() {
return gbuffersBasic.requireValid();
}
public Optional<ProgramSource> getGbuffersBeaconBeam() {
return gbuffersBeaconBeam.requireValid();
}
public Optional<ProgramSource> getGbuffersTextured() {
return gbuffersTextured.requireValid();
}
public Optional<ProgramSource> getGbuffersTexturedLit() {
return gbuffersTexturedLit.requireValid();
}
public Optional<ProgramSource> getGbuffersTerrain() {
return gbuffersTerrain.requireValid();
}
public Optional<ProgramSource> getGbuffersDamagedBlock() {
return gbuffersDamagedBlock.requireValid();
}
public Optional<ProgramSource> getGbuffersSkyBasic() {
return gbuffersSkyBasic.requireValid();
}
public Optional<ProgramSource> getGbuffersSkyTextured() {
return gbuffersSkyTextured.requireValid();
}
public Optional<ProgramSource> getGbuffersClouds() {
return gbuffersClouds.requireValid();
}
public Optional<ProgramSource> getGbuffersWeather() {
return gbuffersWeather.requireValid();
}
public Optional<ProgramSource> getGbuffersEntities() {
return gbuffersEntities.requireValid();
}
public Optional<ProgramSource> getGbuffersEntitiesTrans() {
return gbuffersEntitiesTrans.requireValid();
}
public Optional<ProgramSource> getGbuffersEntitiesGlowing() {
return gbuffersEntitiesGlowing.requireValid();
}
public Optional<ProgramSource> getGbuffersGlint() {
return gbuffersGlint.requireValid();
}
public Optional<ProgramSource> getGbuffersEntityEyes() {
return gbuffersEntityEyes.requireValid();
}
public Optional<ProgramSource> getGbuffersBlock() {
return gbuffersBlock.requireValid();
}
public Optional<ProgramSource> getGbuffersHand() {
return gbuffersHand.requireValid();
}
public Optional<ProgramSource> get(ProgramId programId) {
return switch (programId) {
case Shadow -> getShadow();
case Basic -> getGbuffersBasic();
case Line -> gbuffersLine.requireValid();
case Textured -> getGbuffersTextured();
case TexturedLit -> getGbuffersTexturedLit();
case SkyBasic -> getGbuffersSkyBasic();
case SkyTextured -> getGbuffersSkyTextured();
case Clouds -> getGbuffersClouds();
case Terrain -> getGbuffersTerrain();
case DamagedBlock -> getGbuffersDamagedBlock();
case Block -> getGbuffersBlock();
case BeaconBeam -> getGbuffersBeaconBeam();
case Entities -> getGbuffersEntities();
case EntitiesTrans -> getGbuffersEntitiesTrans();
case EntitiesGlowing -> getGbuffersEntitiesGlowing();
case ArmorGlint -> getGbuffersGlint();
case SpiderEyes -> getGbuffersEntityEyes();
case Hand -> getGbuffersHand();
case Weather -> getGbuffersWeather();
case Water -> getGbuffersWater();
case HandWater -> getGbuffersHandWater();
case Final -> getCompositeFinal();
default -> Optional.empty();
};
}
public ProgramSource[] getDeferred() {
return deferred;
}
public Optional<ProgramSource> getGbuffersWater() {
return gbuffersWater.requireValid();
}
public Optional<ProgramSource> getGbuffersHandWater() {
return gbuffersHandWater.requireValid();
}
public ProgramSource[] getComposite() {
return composite;
}
public Optional<ProgramSource> getCompositeFinal() {
return compositeFinal.requireValid();
}
public ComputeSource[] getShadowCompute() {
return shadowCompute;
}
public ComputeSource[][] getShadowCompCompute() {
return shadowCompCompute;
}
public ComputeSource[][] getPrepareCompute() {
return prepareCompute;
}
public ComputeSource[][] getDeferredCompute() {
return deferredCompute;
}
public ComputeSource[][] getCompositeCompute() {
return compositeCompute;
}
public ComputeSource[] getFinalCompute() {
return finalCompute;
}
public PackDirectives getPackDirectives() {
return packDirectives;
}
public ShaderPack getPack() {
return pack;
}
private static ProgramSource readProgramSource(AbsolutePackPath directory,
Function<AbsolutePackPath, String> sourceProvider, String program,
ProgramSet programSet, ShaderProperties properties) {
return readProgramSource(directory, sourceProvider, program, programSet, properties, null);
}
private static ProgramSource readProgramSource(AbsolutePackPath directory,
Function<AbsolutePackPath, String> sourceProvider, String program,
ProgramSet programSet, ShaderProperties properties,
BlendModeOverride defaultBlendModeOverride) {
AbsolutePackPath vertexPath = directory.resolve(program + ".vsh");
String vertexSource = sourceProvider.apply(vertexPath);
AbsolutePackPath geometryPath = directory.resolve(program + ".gsh");
String geometrySource = sourceProvider.apply(geometryPath);
AbsolutePackPath fragmentPath = directory.resolve(program + ".fsh");
String fragmentSource = sourceProvider.apply(fragmentPath);
return new ProgramSource(program, vertexSource, geometrySource, fragmentSource, programSet, properties,
defaultBlendModeOverride);
}
private static ComputeSource readComputeSource(AbsolutePackPath directory,
Function<AbsolutePackPath, String> sourceProvider, String program,
ProgramSet programSet) {
AbsolutePackPath computePath = directory.resolve(program + ".csh");
String computeSource = sourceProvider.apply(computePath);
if (computeSource == null) {
return null;
}
return new ComputeSource(program, computeSource, programSet);
}
}