Reworked Shaders/Uniforms and started work on GuiComponents
This commit is contained in:
		
							parent
							
								
									6091d8319a
								
							
						
					
					
						commit
						c464aaa271
					
				@ -1,2 +1,13 @@
 | 
			
		||||
connection.project.dir=..
 | 
			
		||||
arguments=
 | 
			
		||||
auto.sync=false
 | 
			
		||||
build.scans.enabled=false
 | 
			
		||||
connection.gradle.distribution=GRADLE_DISTRIBUTION(WRAPPER)
 | 
			
		||||
connection.project.dir=
 | 
			
		||||
eclipse.preferences.version=1
 | 
			
		||||
gradle.user.home=
 | 
			
		||||
java.home=
 | 
			
		||||
jvm.arguments=
 | 
			
		||||
offline.mode=false
 | 
			
		||||
override.workspace.settings=false
 | 
			
		||||
show.console.view=false
 | 
			
		||||
show.executions.view=false
 | 
			
		||||
 | 
			
		||||
@ -17,6 +17,7 @@ sourceCompatibility = targetCompatibility = compileJava.sourceCompatibility = co
 | 
			
		||||
repositories {
 | 
			
		||||
	mavenCentral()
 | 
			
		||||
	maven {
 | 
			
		||||
		name = "Speiger Maven"
 | 
			
		||||
		url = "https://maven.speiger.com/repository/main"
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -25,7 +26,7 @@ task srcJar(type: Jar) {
 | 
			
		||||
	from sourceSets.main.allSource
 | 
			
		||||
	archiveClassifier = 'sources'
 | 
			
		||||
	from {
 | 
			
		||||
		configurations.compile.collect { 
 | 
			
		||||
		configurations.runtimeClasspath.collect { 
 | 
			
		||||
			it.isDirectory() ? it : zipTree(it)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
@ -37,7 +38,7 @@ artifacts {
 | 
			
		||||
 | 
			
		||||
jar {
 | 
			
		||||
	from {
 | 
			
		||||
		configurations.compile.collect { 
 | 
			
		||||
		configurations.runtimeClasspath.collect { 
 | 
			
		||||
			it.isDirectory() ? it : zipTree(it)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -2,11 +2,6 @@ package speiger.src.coreengine;
 | 
			
		||||
 | 
			
		||||
import java.nio.file.Path;
 | 
			
		||||
 | 
			
		||||
import org.lwjgl.opengl.ARBBaseInstance;
 | 
			
		||||
import org.lwjgl.opengl.GL11;
 | 
			
		||||
import org.lwjgl.opengl.GL31;
 | 
			
		||||
import org.lwjgl.opengl.NVMeshShader;
 | 
			
		||||
 | 
			
		||||
import speiger.src.coreengine.application.Application;
 | 
			
		||||
import speiger.src.coreengine.rendering.input.window.Window;
 | 
			
		||||
import speiger.src.coreengine.rendering.input.window.WindowProvider;
 | 
			
		||||
@ -27,12 +22,10 @@ public class Testing extends Application {
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public void init(Path file) {
 | 
			
		||||
		System.out.println(GL11.glGetInteger(GL31.GL_MAX_UNIFORM_BUFFER_BINDINGS));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
	public void update() {
 | 
			
		||||
		System.exit(0);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
 | 
			
		||||
@ -32,15 +32,15 @@ public class GuiBox implements IGuiBox
 | 
			
		||||
		onChanged();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static IGuiBox createSimpleBox(float x, float y, float width, float height) {
 | 
			
		||||
	public static IGuiBox simple(float x, float y, float width, float height) {
 | 
			
		||||
		return new GuiBox(x, y, width, height);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static IGuiBox createParentBox(IGuiBox box) {
 | 
			
		||||
	public static IGuiBox clone(IGuiBox box) {
 | 
			
		||||
		return new GuiBox(box.getMinX(), box.getMinY(), box.getWidth(), box.getHeight());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static IGuiBox createParentBox(IGuiBox box, float padding) {
 | 
			
		||||
	public static IGuiBox clonePadded(IGuiBox box, float padding) {
 | 
			
		||||
		return new GuiBox(box.getMinX() + padding, box.getMinY() + padding, box.getWidth() - padding * 2F, box.getHeight() - padding * 2F);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
@ -14,8 +14,10 @@ public interface IGuiBox extends IScreenBox
 | 
			
		||||
	public IGuiBox getParent();
 | 
			
		||||
	public IGuiBox onChanged();
 | 
			
		||||
	
 | 
			
		||||
	public default IGuiBox copy() { return GuiBox.createParentBox(this); }
 | 
			
		||||
	public default IGuiBox copy(float padding) { return GuiBox.createParentBox(this, padding); }
 | 
			
		||||
	public static IGuiBox of(float x, float y, float width, float height) { return new GuiBox(x, y, width, height); }
 | 
			
		||||
	
 | 
			
		||||
	public default IGuiBox copy() { return GuiBox.clone(this); }
 | 
			
		||||
	public default IGuiBox copy(float padding) { return GuiBox.clonePadded(this, padding); }
 | 
			
		||||
	
 | 
			
		||||
	public float getScale();
 | 
			
		||||
	public float getBaseX();
 | 
			
		||||
 | 
			
		||||
@ -5,10 +5,7 @@ import speiger.src.coreengine.rendering.newGui.components.base.GuiComponent;
 | 
			
		||||
import speiger.src.coreengine.rendering.newGui.components.base.IInteractable;
 | 
			
		||||
 | 
			
		||||
public class TestComponent extends GuiComponent implements IInteractable {
 | 
			
		||||
 | 
			
		||||
	public TestComponent(IGuiBox box) {
 | 
			
		||||
		super(box);
 | 
			
		||||
		// TODO Auto-generated constructor stub
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -5,6 +5,7 @@ import java.util.function.Consumer;
 | 
			
		||||
 | 
			
		||||
import speiger.src.collections.objects.lists.ObjectArrayList;
 | 
			
		||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
 | 
			
		||||
import speiger.src.coreengine.rendering.newGui.renderer.IUIRenderer;
 | 
			
		||||
import speiger.src.coreengine.utils.collections.CollectionUtils;
 | 
			
		||||
import speiger.src.coreengine.utils.collections.FlagObject;
 | 
			
		||||
import speiger.src.coreengine.utils.misc.ICastable;
 | 
			
		||||
@ -21,6 +22,11 @@ public non-sealed class GuiComponent extends FlagObject implements ICastable, IL
 | 
			
		||||
	List<GuiComponent> children = new ObjectArrayList<>();
 | 
			
		||||
	InteractionContainer interactions = new InteractionContainer(this::isInteractable);
 | 
			
		||||
	List<Consumer<GuiComponent>>[] listeners = CollectionUtils.createList(IListableComponent.MAX_LISTENER_TYPES);
 | 
			
		||||
	IComponentRenderer<GuiComponent> renderer;
 | 
			
		||||
	
 | 
			
		||||
	public GuiComponent(float x, float y, float width, float height) {
 | 
			
		||||
		this(IGuiBox.of(x, y, width, height));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public GuiComponent(IGuiBox box) {
 | 
			
		||||
		this.box = box;
 | 
			
		||||
@ -39,6 +45,39 @@ public non-sealed class GuiComponent extends FlagObject implements ICastable, IL
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void updateComponent() {
 | 
			
		||||
		children.forEach(GuiComponent::updateComponent);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	protected void renderComponent(IUIRenderer renderer, int mouseX, int mouseY, float particalTicks) {
 | 
			
		||||
		renderChildren(renderer, mouseX, mouseY, particalTicks);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	protected void renderChildren(IUIRenderer renderer, int mouseX, int mouseY, float particalTicks) {
 | 
			
		||||
		for(GuiComponent child : children) {
 | 
			
		||||
			renderComponent(child, renderer, mouseX, mouseY, particalTicks);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static boolean renderComponent(GuiComponent comp, IUIRenderer renderer, int mouseX, int mouseY, float particalTicks) {
 | 
			
		||||
		if(!comp.isVisible() || comp.isManualManaged() || (comp.isScissored() && !renderer.isInScissors(comp.getBox()))) return false;
 | 
			
		||||
		if(comp.isScissored()) {
 | 
			
		||||
			renderer.pushScissors(comp.getBox());
 | 
			
		||||
			if(comp.renderer != null) {
 | 
			
		||||
				comp.renderer.renderComponent(comp, renderer, mouseX, mouseY, particalTicks);
 | 
			
		||||
				comp.renderChildren(renderer, mouseX, mouseY, particalTicks);
 | 
			
		||||
			}
 | 
			
		||||
			else comp.renderComponent(renderer, mouseX, mouseY, particalTicks);
 | 
			
		||||
			renderer.popScissors();
 | 
			
		||||
		}
 | 
			
		||||
		else if(comp.renderer != null) {
 | 
			
		||||
			comp.renderer.renderComponent(comp, renderer, mouseX, mouseY, particalTicks);
 | 
			
		||||
			comp.renderChildren(renderer, mouseX, mouseY, particalTicks);
 | 
			
		||||
		}
 | 
			
		||||
		else comp.renderComponent(renderer, mouseX, mouseY, particalTicks);
 | 
			
		||||
		return true;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public GuiComponent addListener(Consumer<GuiComponent> listener, int index) {
 | 
			
		||||
		listeners[index].add(listener);
 | 
			
		||||
@ -72,7 +111,7 @@ public non-sealed class GuiComponent extends FlagObject implements ICastable, IL
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public GuiComponent bounds(float width, float height) {
 | 
			
		||||
		if(box.getBaseWidth() != width || box.getBaseHeight() != height) {
 | 
			
		||||
@ -81,7 +120,7 @@ public non-sealed class GuiComponent extends FlagObject implements ICastable, IL
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public GuiComponent resize(float width, float height) {
 | 
			
		||||
		if(width != 0F || height != 0F) {
 | 
			
		||||
@ -90,7 +129,7 @@ public non-sealed class GuiComponent extends FlagObject implements ICastable, IL
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public GuiComponent move(float moveX, float moveY) {
 | 
			
		||||
		if(moveX != 0F || moveY != 0F) {
 | 
			
		||||
@ -147,4 +186,4 @@ public non-sealed class GuiComponent extends FlagObject implements ICastable, IL
 | 
			
		||||
		setFlag(FLAG_SCISSORED, value);
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -0,0 +1,7 @@
 | 
			
		||||
package speiger.src.coreengine.rendering.newGui.components.base;
 | 
			
		||||
 | 
			
		||||
import speiger.src.coreengine.rendering.newGui.renderer.IUIRenderer;
 | 
			
		||||
 | 
			
		||||
public interface IComponentRenderer<T extends GuiComponent> {
 | 
			
		||||
	public void renderComponent(T component, IUIRenderer renderer, int mouseX, int mouseY, float particalTicks);
 | 
			
		||||
}
 | 
			
		||||
@ -37,6 +37,10 @@ public interface ILayoutComponent {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static class ArrayFetcher implements ILayoutScanner {
 | 
			
		||||
		private static final int INDEX_MIN_X = 0;
 | 
			
		||||
		private static final int INDEX_MIN_Y = 1;
 | 
			
		||||
		private static final int INDEX_MAX_X = 2;
 | 
			
		||||
		private static final int INDEX_MAX_Y = 3;
 | 
			
		||||
		float[] result = new float[] {Float.MAX_VALUE, Float.MAX_VALUE, -Float.MAX_VALUE, -Float.MAX_VALUE};
 | 
			
		||||
		boolean includeInvisible = false;
 | 
			
		||||
		
 | 
			
		||||
@ -51,10 +55,10 @@ public interface ILayoutComponent {
 | 
			
		||||
		
 | 
			
		||||
		@Override
 | 
			
		||||
		public void accept(float minX, float minY, float maxX, float maxY) {
 | 
			
		||||
			result[0] = Math.min(minX, result[0]);
 | 
			
		||||
			result[1] = Math.min(minX, result[1]);
 | 
			
		||||
			result[2] = Math.max(minX, result[2]);
 | 
			
		||||
			result[3] = Math.max(minX, result[3]);
 | 
			
		||||
			result[INDEX_MIN_X] = Math.min(minX, result[INDEX_MIN_X]);
 | 
			
		||||
			result[INDEX_MIN_Y] = Math.min(minY, result[INDEX_MIN_Y]);
 | 
			
		||||
			result[INDEX_MAX_X] = Math.max(maxX, result[INDEX_MAX_X]);
 | 
			
		||||
			result[INDEX_MAX_Y] = Math.max(maxY, result[INDEX_MAX_Y]);
 | 
			
		||||
		}
 | 
			
		||||
		
 | 
			
		||||
		public float[] getResult() {
 | 
			
		||||
 | 
			
		||||
@ -10,7 +10,6 @@ import speiger.src.collections.objects.utils.ObjectLists;
 | 
			
		||||
import speiger.src.coreengine.rendering.newGui.components.base.IInteractableContainer.IRecursiveInteractionContainer;
 | 
			
		||||
 | 
			
		||||
public class InteractionContainer implements IRecursiveInteractionContainer {
 | 
			
		||||
	
 | 
			
		||||
	List<IInteractable> children = new ObjectArrayList<>();
 | 
			
		||||
	IInteractable focused;
 | 
			
		||||
	IntSet activeButtons = new IntOpenHashSet();
 | 
			
		||||
 | 
			
		||||
@ -1,8 +1,9 @@
 | 
			
		||||
package speiger.src.coreengine.rendering.newGui.renderer;
 | 
			
		||||
 | 
			
		||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
 | 
			
		||||
 | 
			
		||||
public interface IUIRenderer {
 | 
			
		||||
	public IUIRenderer drawQuad(float minX, float minY, float maxX, float maxY, float zOff, int color);
 | 
			
		||||
	public IUIRenderer drawTexturedQuad(float minX, float minY, float maxX, float maxY, float zOff, int color);
 | 
			
		||||
	public IUIRenderer drawLine(float minX, float minY, float maxX, float maxY, float zOff, int color);
 | 
			
		||||
	public IUIRenderer drawFrame(float minX, float minY, float maxX, float maxY, float zOff, int color);
 | 
			
		||||
	public boolean isInScissors(IGuiBox box);
 | 
			
		||||
	public void pushScissors(IGuiBox box);
 | 
			
		||||
	public void popScissors();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -4,26 +4,47 @@ import java.util.function.Function;
 | 
			
		||||
import java.util.function.Supplier;
 | 
			
		||||
 | 
			
		||||
import speiger.src.coreengine.assets.base.IAssetProvider;
 | 
			
		||||
import speiger.src.coreengine.rendering.utils.GLStateTracker;
 | 
			
		||||
 | 
			
		||||
public class Shader<T extends ShaderProgram> implements Supplier<T> {
 | 
			
		||||
	T program;
 | 
			
		||||
	Function<IAssetProvider, T> provider;
 | 
			
		||||
	
 | 
			
		||||
	public Shader(Function<IAssetProvider, T> provider) {
 | 
			
		||||
	private Shader(Function<IAssetProvider, T> provider) {
 | 
			
		||||
		this.provider = provider;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static <T extends ShaderProgram> Shader<T> create(Function<IAssetProvider, T> provider) {
 | 
			
		||||
		return new Shader<>(provider);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static <T extends ShaderProgram> Shader<T> createAndRegister(Function<IAssetProvider, T> provider) {
 | 
			
		||||
		Shader<T> shader = new Shader<>(provider);
 | 
			
		||||
		GLStateTracker.SHADERS.register(shader);
 | 
			
		||||
		return shader;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void load(IAssetProvider provider) {
 | 
			
		||||
		if(program != null) program.remove();
 | 
			
		||||
		program = this.provider.apply(provider);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void validate() {
 | 
			
		||||
		if(program == null) return;
 | 
			
		||||
		program.validateProgram();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void remove() {
 | 
			
		||||
		if(program == null) return;
 | 
			
		||||
		program.remove();
 | 
			
		||||
		program = null;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void removeProgram() {
 | 
			
		||||
		remove();
 | 
			
		||||
		GLStateTracker.SHADERS.remove(this);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public T get() { return program; }
 | 
			
		||||
}
 | 
			
		||||
@ -11,29 +11,46 @@ import org.lwjgl.opengl.GL46;
 | 
			
		||||
import org.lwjgl.system.MemoryUtil;
 | 
			
		||||
 | 
			
		||||
import speiger.src.collections.objects.maps.interfaces.Object2ObjectMap;
 | 
			
		||||
import speiger.src.collections.objects.utils.maps.Object2ObjectMaps;
 | 
			
		||||
import speiger.src.coreengine.assets.AssetLocation;
 | 
			
		||||
import speiger.src.coreengine.assets.base.IAsset;
 | 
			
		||||
import speiger.src.coreengine.assets.base.IAssetProvider;
 | 
			
		||||
import speiger.src.coreengine.math.ArrayUtil;
 | 
			
		||||
import speiger.src.coreengine.rendering.shader.uniform.UniformManager;
 | 
			
		||||
import speiger.src.coreengine.rendering.utils.GLStateTracker;
 | 
			
		||||
import speiger.src.coreengine.rendering.utils.values.IGLValue.IShaderType;
 | 
			
		||||
import speiger.src.coreengine.utils.io.GameLog;
 | 
			
		||||
 | 
			
		||||
public abstract class ShaderProgram {
 | 
			
		||||
	static final Map<AssetLocation, String> IMPORTS = Object2ObjectMaps.synchronize(Object2ObjectMap.builder().map());
 | 
			
		||||
	static final Map<AssetLocation, String> IMPORTS = Object2ObjectMap.builder().<AssetLocation, String>map().synchronize();
 | 
			
		||||
	protected final UniformManager uniforms = new UniformManager(this);
 | 
			
		||||
	private int id;
 | 
			
		||||
	
 | 
			
		||||
	public boolean isValid() { return id != 0; }
 | 
			
		||||
	public abstract boolean isActive();
 | 
			
		||||
	public boolean isActive() { return GLStateTracker.SHADERS.isShaderActive(this); }
 | 
			
		||||
	public int id() { return id; }
 | 
			
		||||
	public abstract void bind();
 | 
			
		||||
	public abstract void unbind();
 | 
			
		||||
	public abstract void remove();
 | 
			
		||||
	public UniformManager getUniforms() { return uniforms; }
 | 
			
		||||
	
 | 
			
		||||
	public void bind() {
 | 
			
		||||
		GLStateTracker.SHADERS.bind(this);
 | 
			
		||||
		uniforms.bind();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void remove() {
 | 
			
		||||
		if(id == 0) return;
 | 
			
		||||
		uniforms.remove();
 | 
			
		||||
		GL20.glDeleteProgram(id);
 | 
			
		||||
		id = 0;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void validateProgram() {
 | 
			
		||||
		if(id == 0) return;
 | 
			
		||||
		GL46.glValidateProgram(id);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public static int loadOrGenerateCache(String location, FileTime newestResource, IntPredicate callback) {
 | 
			
		||||
		int id = GL20.glCreateProgram();
 | 
			
		||||
		boolean fail = true;
 | 
			
		||||
		if(!loadFromBinary(id, location, newestResource) && callback.test(id)) {
 | 
			
		||||
		if((fail = !loadFromBinary(id, location, newestResource)) && callback.test(id)) {
 | 
			
		||||
			if(GL46.glGetProgrami(id, GL46.GL_LINK_STATUS) == GL46.GL_TRUE) {
 | 
			
		||||
				if(ShaderCache.INSTANCE.hasCache()) ShaderCache.INSTANCE.storeInCache(location, getProgramBytes(id));
 | 
			
		||||
				fail = false;
 | 
			
		||||
@ -69,10 +86,10 @@ public abstract class ShaderProgram {
 | 
			
		||||
			for(String line : asset.lines()) {
 | 
			
		||||
				if(line.startsWith("//")) continue;
 | 
			
		||||
				if(line.startsWith("#import<") && line.endsWith(">")) {
 | 
			
		||||
					builder.append(importLines(provider, AssetLocation.of(line.substring(8, line.length()-1)))).append("//\n");
 | 
			
		||||
					builder.append(importLines(provider, AssetLocation.of(line.substring(8, line.length()-1)))).append("\n");
 | 
			
		||||
					continue;
 | 
			
		||||
				}
 | 
			
		||||
				builder.append(line).append("//\n");
 | 
			
		||||
				builder.append(line).append("\n");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		catch(Exception e) {
 | 
			
		||||
@ -97,7 +114,7 @@ public abstract class ShaderProgram {
 | 
			
		||||
				StringBuilder builder = new StringBuilder();
 | 
			
		||||
				for(String line : asset.lines()) {
 | 
			
		||||
					if(line.startsWith("//")) continue;
 | 
			
		||||
					builder.append(line).append("//\n");
 | 
			
		||||
					builder.append(line).append("\n");
 | 
			
		||||
				}
 | 
			
		||||
				return builder.toString();
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
@ -10,12 +10,16 @@ import speiger.src.coreengine.assets.base.IReloadableAsset.ISimpleRealodableAsse
 | 
			
		||||
 | 
			
		||||
public class ShaderTracker implements ISimpleRealodableAsset, IManagedAsset {
 | 
			
		||||
	ObjectList<Shader<?>> shaders = new ObjectArrayList<>();
 | 
			
		||||
	int shader;
 | 
			
		||||
	int activeShaderId;
 | 
			
		||||
	IAssetProvider provider;
 | 
			
		||||
		
 | 
			
		||||
	public void registerShader(Shader<?> shader) {
 | 
			
		||||
	public void register(Shader<?> shader) {
 | 
			
		||||
		shaders.add(shader);
 | 
			
		||||
		shader.load(provider);
 | 
			
		||||
		load(provider, shader);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void remove(Shader<?> shader) {
 | 
			
		||||
		shaders.remove(shader);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void bind(ShaderProgram program) {
 | 
			
		||||
@ -23,19 +27,16 @@ public class ShaderTracker implements ISimpleRealodableAsset, IManagedAsset {
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void bind(int shaderId) {
 | 
			
		||||
		if(shader == shaderId) return;
 | 
			
		||||
		shader = shaderId;
 | 
			
		||||
		if(activeShaderId == shaderId) return;
 | 
			
		||||
		activeShaderId = shaderId;
 | 
			
		||||
		GL20.glUseProgram(shaderId);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void unbind() {
 | 
			
		||||
		if(shader == 0) return;
 | 
			
		||||
		shader = 0;
 | 
			
		||||
		GL20.glUseProgram(0);
 | 
			
		||||
	}
 | 
			
		||||
	public void unbind() { bind(0); }
 | 
			
		||||
	
 | 
			
		||||
	public boolean isActive() { return shader != 0; }
 | 
			
		||||
	public int getActiveShader() { return shader; }
 | 
			
		||||
	public boolean isActive() { return activeShaderId != 0; }
 | 
			
		||||
	public boolean isShaderActive(ShaderProgram program) { return activeShaderId == shaderId(program); }
 | 
			
		||||
	public int getActiveShader() { return activeShaderId; }
 | 
			
		||||
	
 | 
			
		||||
	private int shaderId(ShaderProgram program) {
 | 
			
		||||
		return program == null ? 0 : program.id();
 | 
			
		||||
@ -45,7 +46,7 @@ public class ShaderTracker implements ISimpleRealodableAsset, IManagedAsset {
 | 
			
		||||
	public void destroy() {
 | 
			
		||||
		shaders.forEach(Shader::remove);
 | 
			
		||||
		shaders.clear();
 | 
			
		||||
		shader = 0;
 | 
			
		||||
		activeShaderId = 0;
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	@Override
 | 
			
		||||
@ -56,10 +57,11 @@ public class ShaderTracker implements ISimpleRealodableAsset, IManagedAsset {
 | 
			
		||||
	public void onAssetsReloaded(IAssetProvider provider) {
 | 
			
		||||
		ShaderProgram.IMPORTS.clear();
 | 
			
		||||
		shaders.forEach(provider, this::load);
 | 
			
		||||
		shader = 0;
 | 
			
		||||
		activeShaderId = 0;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	private void load(IAssetProvider provider, Shader<?> shader) {
 | 
			
		||||
		shader.load(provider);
 | 
			
		||||
		shader.validate();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,32 @@
 | 
			
		||||
package speiger.src.coreengine.rendering.shader.uniform;
 | 
			
		||||
 | 
			
		||||
import java.util.Objects;
 | 
			
		||||
 | 
			
		||||
import speiger.src.collections.objects.maps.interfaces.Object2ObjectMap;
 | 
			
		||||
 | 
			
		||||
public class GlobalUniforms {
 | 
			
		||||
	private Object2ObjectMap<String, IUniform> uniforms = Object2ObjectMap.builder().map();
 | 
			
		||||
	
 | 
			
		||||
	public <T extends IUniform> T register(T uniform) {
 | 
			
		||||
		uniforms.putIfAbsent(Objects.requireNonNull(uniform.getName()), uniform);
 | 
			
		||||
		return uniform;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public boolean contains(String name) {
 | 
			
		||||
		return uniforms.containsKey(name);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public <T extends IUniform> T get(String name) {
 | 
			
		||||
		return (T)uniforms.get(name);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@SuppressWarnings("unchecked")
 | 
			
		||||
	public <T extends IUniform> T getOrDefault(String name, T defaultValue) {
 | 
			
		||||
		return (T)uniforms.getOrDefault(name, defaultValue);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Object2ObjectMap<String, IUniform> getAll() {
 | 
			
		||||
		return uniforms.unmodifiable();
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -3,6 +3,7 @@ package speiger.src.coreengine.rendering.shader.uniform;
 | 
			
		||||
import speiger.src.coreengine.rendering.shader.ShaderProgram;
 | 
			
		||||
 | 
			
		||||
public interface IUniform {
 | 
			
		||||
	public String getName();
 | 
			
		||||
	public void registerShader(ShaderProgram program);
 | 
			
		||||
	public void removeShader(ShaderProgram program);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -16,6 +16,11 @@ public abstract class Uniform implements IUniform {
 | 
			
		||||
		positions.setDefaultReturnValue(-1);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	public String getName() {
 | 
			
		||||
		return name;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	protected int getPosition(ShaderProgram program) {
 | 
			
		||||
		return positions.get(program.id());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -0,0 +1,96 @@
 | 
			
		||||
package speiger.src.coreengine.rendering.shader.uniform;
 | 
			
		||||
 | 
			
		||||
import java.util.List;
 | 
			
		||||
 | 
			
		||||
import speiger.src.collections.objects.lists.ObjectArrayList;
 | 
			
		||||
import speiger.src.coreengine.math.vector.floats.Vec2f;
 | 
			
		||||
import speiger.src.coreengine.math.vector.floats.Vec3f;
 | 
			
		||||
import speiger.src.coreengine.math.vector.floats.Vec4f;
 | 
			
		||||
import speiger.src.coreengine.math.vector.matrix.Matrix4f;
 | 
			
		||||
import speiger.src.coreengine.rendering.shader.ShaderProgram;
 | 
			
		||||
import speiger.src.coreengine.rendering.shader.uniform.base.BoolUniform;
 | 
			
		||||
import speiger.src.coreengine.rendering.shader.uniform.base.BufferUniform;
 | 
			
		||||
import speiger.src.coreengine.rendering.shader.uniform.base.FloatUniform;
 | 
			
		||||
import speiger.src.coreengine.rendering.shader.uniform.base.IntUniform;
 | 
			
		||||
import speiger.src.coreengine.rendering.shader.uniform.base.TextureUniform;
 | 
			
		||||
import speiger.src.coreengine.rendering.shader.uniform.vec.Matrix4fUniform;
 | 
			
		||||
import speiger.src.coreengine.rendering.shader.uniform.vec.Vec2fUniform;
 | 
			
		||||
import speiger.src.coreengine.rendering.shader.uniform.vec.Vec3fUniform;
 | 
			
		||||
import speiger.src.coreengine.rendering.shader.uniform.vec.Vec4fUniform;
 | 
			
		||||
import speiger.src.coreengine.rendering.utils.GLStateTracker;
 | 
			
		||||
 | 
			
		||||
public class UniformManager {
 | 
			
		||||
	List<IUniform> uniforms = new ObjectArrayList<>();
 | 
			
		||||
	List<IAutoUniform> autoUniforms = new ObjectArrayList<>();
 | 
			
		||||
	ShaderProgram owner;
 | 
			
		||||
	
 | 
			
		||||
	public UniformManager(ShaderProgram owner) {
 | 
			
		||||
		this.owner = owner;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public <T extends IUniform> T addGlobalUniform(String name) {
 | 
			
		||||
		return addUniform(GLStateTracker.UNIFORMS.get(name));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public <T extends IUniform> T addGlobalUniform(String name, T defaultValue) {
 | 
			
		||||
		return addUniform(GLStateTracker.UNIFORMS.getOrDefault(name, defaultValue));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public BoolUniform addBool(String name, boolean defaultValue) { 
 | 
			
		||||
		return addUniform(new BoolUniform(name, defaultValue));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public IntUniform addInt(String name, int defaultValue)  {
 | 
			
		||||
		return addUniform(new IntUniform(name, defaultValue));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public FloatUniform addFloat(String name, float defaultValue) { 
 | 
			
		||||
		return addUniform(new FloatUniform(name, defaultValue));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Vec2fUniform addVec2(String name, Vec2f defaultValue) {
 | 
			
		||||
		return addUniform(new Vec2fUniform(name, defaultValue.copyAsMutable()));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Vec3fUniform addVec3(String name, Vec3f defaultValue) {
 | 
			
		||||
		return addUniform(new Vec3fUniform(name, defaultValue.copyAsMutable()));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Vec4fUniform addVec4(String name, Vec4f defaultValue) {
 | 
			
		||||
		return addUniform(new Vec4fUniform(name, defaultValue.copyAsMutable()));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Matrix4fUniform addMat(String name, Matrix4f defaultValue) {
 | 
			
		||||
		return addUniform(new Matrix4fUniform(name, new Matrix4f(defaultValue)));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public BufferUniform addBuffer(String name, int slot) { 
 | 
			
		||||
		return addUniform(new BufferUniform(name, slot));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public TextureUniform addTexture(String name, int unit) {
 | 
			
		||||
		return addUniform(new TextureUniform(name, unit));
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public <T extends IUniform> T addUniform(T uniform) {
 | 
			
		||||
		uniforms.add(uniform);
 | 
			
		||||
		uniform.registerShader(owner);
 | 
			
		||||
		if(uniform instanceof IAutoUniform auto) {
 | 
			
		||||
			autoUniforms.add(auto);
 | 
			
		||||
		}
 | 
			
		||||
		return uniform;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void bind() {
 | 
			
		||||
		if(autoUniforms.isEmpty()) return;
 | 
			
		||||
		for(int i = 0,m=autoUniforms.size();i<m;i++) {
 | 
			
		||||
			autoUniforms.get(i).bind(owner);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public void remove() {
 | 
			
		||||
		for(int i = 0,m=uniforms.size();i<m;i++) {
 | 
			
		||||
			uniforms.get(i).removeShader(owner);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
} 
 | 
			
		||||
@ -0,0 +1,37 @@
 | 
			
		||||
package speiger.src.coreengine.rendering.shader.uniform.vec;
 | 
			
		||||
 | 
			
		||||
import java.util.Arrays;
 | 
			
		||||
 | 
			
		||||
import org.lwjgl.opengl.GL41;
 | 
			
		||||
 | 
			
		||||
import speiger.src.coreengine.math.vector.matrix.Matrix4f;
 | 
			
		||||
import speiger.src.coreengine.rendering.shader.uniform.Uniform;
 | 
			
		||||
import speiger.src.coreengine.rendering.utils.AllocationTracker;
 | 
			
		||||
 | 
			
		||||
public class Matrix4fUniform extends Uniform {
 | 
			
		||||
	Matrix4f value;
 | 
			
		||||
	
 | 
			
		||||
	public Matrix4fUniform(String name, Matrix4f value) {
 | 
			
		||||
		super(name);
 | 
			
		||||
		this.value = value;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Matrix4fUniform set(Matrix4f newMat) {
 | 
			
		||||
		if(hasChanged(newMat)) {
 | 
			
		||||
			value.load(newMat);
 | 
			
		||||
			update();
 | 
			
		||||
		}
 | 
			
		||||
		return this;
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	protected boolean hasChanged(Matrix4f input) {
 | 
			
		||||
		if(value.properties() != input.properties()) return true;
 | 
			
		||||
		return !Arrays.equals(value.getData(), input.getData());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	@Override
 | 
			
		||||
	protected void processChanges(int programId, int location) {
 | 
			
		||||
		GL41.glProgramUniformMatrix4fv(programId, location, false, value.getData());
 | 
			
		||||
		AllocationTracker.INSTANCE.addGPUBytes(64L);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@ -14,6 +14,14 @@ public class Vec2fUniform extends Uniform {
 | 
			
		||||
		this.value = value.asMutable();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Vec2fUniform setX(float value) {
 | 
			
		||||
		return this.value.x() == value ? this : set(value, this.value.y());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Vec2fUniform setY(float value) {
 | 
			
		||||
		return this.value.y() == value ? this : set(this.value.x(), value);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Vec2fUniform set(Vec2f value) {
 | 
			
		||||
		return set(value.x(), value.y());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,18 @@ public class Vec3fUniform extends Uniform {
 | 
			
		||||
		this.value = value.asMutable();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Vec3fUniform setX(float value) {
 | 
			
		||||
		return this.value.x() == value ? this : set(value, this.value.y(), this.value.z());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Vec3fUniform setY(float value) {
 | 
			
		||||
		return this.value.y() == value ? this : set(this.value.x(), value, this.value.z());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Vec3fUniform setZ(float value) {
 | 
			
		||||
		return this.value.z() == value ? this : set(this.value.x(), this.value.y(), value);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Vec3fUniform set(Vec3f value) {
 | 
			
		||||
		return set(value.x(), value.y(), value.z());
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
@ -14,6 +14,22 @@ public class Vec4fUniform extends Uniform {
 | 
			
		||||
		this.value = value.asMutable();
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Vec4fUniform setX(float value) {
 | 
			
		||||
		return this.value.x() == value ? this : set(value, this.value.y(), this.value.z(), this.value.w());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Vec4fUniform setY(float value) {
 | 
			
		||||
		return this.value.y() == value ? this : set(this.value.x(), value, this.value.z(), this.value.w());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Vec4fUniform setZ(float value) {
 | 
			
		||||
		return this.value.z() == value ? this : set(this.value.x(), this.value.y(), value, this.value.w());
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Vec4fUniform setW(float value) {
 | 
			
		||||
		return this.value.w() == value ? this : set(this.value.x(), this.value.y(), this.value.z(), value);
 | 
			
		||||
	}
 | 
			
		||||
	
 | 
			
		||||
	public Vec4fUniform set(Vec4f value) {
 | 
			
		||||
		return set(value.x(), value.y(), value.z(), value.w());
 | 
			
		||||
	}
 | 
			
		||||
@ -31,4 +47,4 @@ public class Vec4fUniform extends Uniform {
 | 
			
		||||
		GL41.glProgramUniform4f(programId, location, value.x(), value.y(), value.z(), value.w());
 | 
			
		||||
		AllocationTracker.INSTANCE.addGPUBytes(16L);
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
}
 | 
			
		||||
@ -87,7 +87,7 @@ public abstract class ShaderProgram
 | 
			
		||||
			for(String s : IterableWrapper.wrap(asset.reader()))
 | 
			
		||||
			{
 | 
			
		||||
				if(s.startsWith("//")) continue;
 | 
			
		||||
				shaderSource.append(s).append("//\n");
 | 
			
		||||
				shaderSource.append(s).append("\n");
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
		catch(Exception e) {
 | 
			
		||||
 | 
			
		||||
@ -10,6 +10,7 @@ import org.lwjgl.opengl.GL44;
 | 
			
		||||
import speiger.src.collections.objects.lists.ObjectArrayList;
 | 
			
		||||
import speiger.src.collections.objects.lists.ObjectList;
 | 
			
		||||
import speiger.src.coreengine.rendering.shader.ShaderTracker;
 | 
			
		||||
import speiger.src.coreengine.rendering.shader.uniform.GlobalUniforms;
 | 
			
		||||
import speiger.src.coreengine.rendering.utils.states.BlendState;
 | 
			
		||||
import speiger.src.coreengine.rendering.utils.states.CullState;
 | 
			
		||||
import speiger.src.coreengine.rendering.utils.states.FloatState;
 | 
			
		||||
@ -36,6 +37,7 @@ public class GLStateTracker {
 | 
			
		||||
	public static final Counter[] COUNTERS = Counter.createCounters(4);
 | 
			
		||||
	public static final ViewPortStack VIEW_PORT = new ViewPortStack();
 | 
			
		||||
	public static final ShaderTracker SHADERS = new ShaderTracker();
 | 
			
		||||
	public static final GlobalUniforms UNIFORMS = new GlobalUniforms();
 | 
			
		||||
	public static final TextureState TEXTURES = addState(new TextureState());
 | 
			
		||||
	
 | 
			
		||||
	public static <T extends IGLState> T addState(T state) {
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user