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
|
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 {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven {
|
maven {
|
||||||
|
name = "Speiger Maven"
|
||||||
url = "https://maven.speiger.com/repository/main"
|
url = "https://maven.speiger.com/repository/main"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +26,7 @@ task srcJar(type: Jar) {
|
||||||
from sourceSets.main.allSource
|
from sourceSets.main.allSource
|
||||||
archiveClassifier = 'sources'
|
archiveClassifier = 'sources'
|
||||||
from {
|
from {
|
||||||
configurations.compile.collect {
|
configurations.runtimeClasspath.collect {
|
||||||
it.isDirectory() ? it : zipTree(it)
|
it.isDirectory() ? it : zipTree(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -37,7 +38,7 @@ artifacts {
|
||||||
|
|
||||||
jar {
|
jar {
|
||||||
from {
|
from {
|
||||||
configurations.compile.collect {
|
configurations.runtimeClasspath.collect {
|
||||||
it.isDirectory() ? it : zipTree(it)
|
it.isDirectory() ? it : zipTree(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,11 +2,6 @@ package speiger.src.coreengine;
|
||||||
|
|
||||||
import java.nio.file.Path;
|
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.application.Application;
|
||||||
import speiger.src.coreengine.rendering.input.window.Window;
|
import speiger.src.coreengine.rendering.input.window.Window;
|
||||||
import speiger.src.coreengine.rendering.input.window.WindowProvider;
|
import speiger.src.coreengine.rendering.input.window.WindowProvider;
|
||||||
|
@ -27,12 +22,10 @@ public class Testing extends Application {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void init(Path file) {
|
public void init(Path file) {
|
||||||
System.out.println(GL11.glGetInteger(GL31.GL_MAX_UNIFORM_BUFFER_BINDINGS));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void update() {
|
public void update() {
|
||||||
System.exit(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -32,15 +32,15 @@ public class GuiBox implements IGuiBox
|
||||||
onChanged();
|
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);
|
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());
|
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);
|
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 getParent();
|
||||||
public IGuiBox onChanged();
|
public IGuiBox onChanged();
|
||||||
|
|
||||||
public default IGuiBox copy() { return GuiBox.createParentBox(this); }
|
public static IGuiBox of(float x, float y, float width, float height) { return new GuiBox(x, y, width, height); }
|
||||||
public default IGuiBox copy(float padding) { return GuiBox.createParentBox(this, padding); }
|
|
||||||
|
public default IGuiBox copy() { return GuiBox.clone(this); }
|
||||||
|
public default IGuiBox copy(float padding) { return GuiBox.clonePadded(this, padding); }
|
||||||
|
|
||||||
public float getScale();
|
public float getScale();
|
||||||
public float getBaseX();
|
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;
|
import speiger.src.coreengine.rendering.newGui.components.base.IInteractable;
|
||||||
|
|
||||||
public class TestComponent extends GuiComponent implements IInteractable {
|
public class TestComponent extends GuiComponent implements IInteractable {
|
||||||
|
|
||||||
public TestComponent(IGuiBox box) {
|
public TestComponent(IGuiBox box) {
|
||||||
super(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.collections.objects.lists.ObjectArrayList;
|
||||||
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
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.CollectionUtils;
|
||||||
import speiger.src.coreengine.utils.collections.FlagObject;
|
import speiger.src.coreengine.utils.collections.FlagObject;
|
||||||
import speiger.src.coreengine.utils.misc.ICastable;
|
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<>();
|
List<GuiComponent> children = new ObjectArrayList<>();
|
||||||
InteractionContainer interactions = new InteractionContainer(this::isInteractable);
|
InteractionContainer interactions = new InteractionContainer(this::isInteractable);
|
||||||
List<Consumer<GuiComponent>>[] listeners = CollectionUtils.createList(IListableComponent.MAX_LISTENER_TYPES);
|
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) {
|
public GuiComponent(IGuiBox box) {
|
||||||
this.box = 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
|
@Override
|
||||||
public GuiComponent addListener(Consumer<GuiComponent> listener, int index) {
|
public GuiComponent addListener(Consumer<GuiComponent> listener, int index) {
|
||||||
listeners[index].add(listener);
|
listeners[index].add(listener);
|
||||||
|
@ -72,7 +111,7 @@ public non-sealed class GuiComponent extends FlagObject implements ICastable, IL
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuiComponent bounds(float width, float height) {
|
public GuiComponent bounds(float width, float height) {
|
||||||
if(box.getBaseWidth() != width || box.getBaseHeight() != height) {
|
if(box.getBaseWidth() != width || box.getBaseHeight() != height) {
|
||||||
|
@ -81,7 +120,7 @@ public non-sealed class GuiComponent extends FlagObject implements ICastable, IL
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuiComponent resize(float width, float height) {
|
public GuiComponent resize(float width, float height) {
|
||||||
if(width != 0F || height != 0F) {
|
if(width != 0F || height != 0F) {
|
||||||
|
@ -90,7 +129,7 @@ public non-sealed class GuiComponent extends FlagObject implements ICastable, IL
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public GuiComponent move(float moveX, float moveY) {
|
public GuiComponent move(float moveX, float moveY) {
|
||||||
if(moveX != 0F || moveY != 0F) {
|
if(moveX != 0F || moveY != 0F) {
|
||||||
|
@ -147,4 +186,4 @@ public non-sealed class GuiComponent extends FlagObject implements ICastable, IL
|
||||||
setFlag(FLAG_SCISSORED, value);
|
setFlag(FLAG_SCISSORED, value);
|
||||||
return this;
|
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 {
|
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};
|
float[] result = new float[] {Float.MAX_VALUE, Float.MAX_VALUE, -Float.MAX_VALUE, -Float.MAX_VALUE};
|
||||||
boolean includeInvisible = false;
|
boolean includeInvisible = false;
|
||||||
|
|
||||||
|
@ -51,10 +55,10 @@ public interface ILayoutComponent {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void accept(float minX, float minY, float maxX, float maxY) {
|
public void accept(float minX, float minY, float maxX, float maxY) {
|
||||||
result[0] = Math.min(minX, result[0]);
|
result[INDEX_MIN_X] = Math.min(minX, result[INDEX_MIN_X]);
|
||||||
result[1] = Math.min(minX, result[1]);
|
result[INDEX_MIN_Y] = Math.min(minY, result[INDEX_MIN_Y]);
|
||||||
result[2] = Math.max(minX, result[2]);
|
result[INDEX_MAX_X] = Math.max(maxX, result[INDEX_MAX_X]);
|
||||||
result[3] = Math.max(minX, result[3]);
|
result[INDEX_MAX_Y] = Math.max(maxY, result[INDEX_MAX_Y]);
|
||||||
}
|
}
|
||||||
|
|
||||||
public float[] getResult() {
|
public float[] getResult() {
|
||||||
|
|
|
@ -10,7 +10,6 @@ import speiger.src.collections.objects.utils.ObjectLists;
|
||||||
import speiger.src.coreengine.rendering.newGui.components.base.IInteractableContainer.IRecursiveInteractionContainer;
|
import speiger.src.coreengine.rendering.newGui.components.base.IInteractableContainer.IRecursiveInteractionContainer;
|
||||||
|
|
||||||
public class InteractionContainer implements IRecursiveInteractionContainer {
|
public class InteractionContainer implements IRecursiveInteractionContainer {
|
||||||
|
|
||||||
List<IInteractable> children = new ObjectArrayList<>();
|
List<IInteractable> children = new ObjectArrayList<>();
|
||||||
IInteractable focused;
|
IInteractable focused;
|
||||||
IntSet activeButtons = new IntOpenHashSet();
|
IntSet activeButtons = new IntOpenHashSet();
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
package speiger.src.coreengine.rendering.newGui.renderer;
|
package speiger.src.coreengine.rendering.newGui.renderer;
|
||||||
|
|
||||||
|
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
||||||
|
|
||||||
public interface IUIRenderer {
|
public interface IUIRenderer {
|
||||||
public IUIRenderer drawQuad(float minX, float minY, float maxX, float maxY, float zOff, int color);
|
public boolean isInScissors(IGuiBox box);
|
||||||
public IUIRenderer drawTexturedQuad(float minX, float minY, float maxX, float maxY, float zOff, int color);
|
public void pushScissors(IGuiBox box);
|
||||||
public IUIRenderer drawLine(float minX, float minY, float maxX, float maxY, float zOff, int color);
|
public void popScissors();
|
||||||
public IUIRenderer drawFrame(float minX, float minY, float maxX, float maxY, float zOff, int color);
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,26 +4,47 @@ import java.util.function.Function;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
import speiger.src.coreengine.assets.base.IAssetProvider;
|
import speiger.src.coreengine.assets.base.IAssetProvider;
|
||||||
|
import speiger.src.coreengine.rendering.utils.GLStateTracker;
|
||||||
|
|
||||||
public class Shader<T extends ShaderProgram> implements Supplier<T> {
|
public class Shader<T extends ShaderProgram> implements Supplier<T> {
|
||||||
T program;
|
T program;
|
||||||
Function<IAssetProvider, T> provider;
|
Function<IAssetProvider, T> provider;
|
||||||
|
|
||||||
public Shader(Function<IAssetProvider, T> provider) {
|
private Shader(Function<IAssetProvider, T> provider) {
|
||||||
this.provider = 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) {
|
public void load(IAssetProvider provider) {
|
||||||
if(program != null) program.remove();
|
if(program != null) program.remove();
|
||||||
program = this.provider.apply(provider);
|
program = this.provider.apply(provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void validate() {
|
||||||
|
if(program == null) return;
|
||||||
|
program.validateProgram();
|
||||||
|
}
|
||||||
|
|
||||||
public void remove() {
|
public void remove() {
|
||||||
if(program == null) return;
|
if(program == null) return;
|
||||||
program.remove();
|
program.remove();
|
||||||
program = null;
|
program = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void removeProgram() {
|
||||||
|
remove();
|
||||||
|
GLStateTracker.SHADERS.remove(this);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public T get() { return program; }
|
public T get() { return program; }
|
||||||
}
|
}
|
|
@ -11,29 +11,46 @@ import org.lwjgl.opengl.GL46;
|
||||||
import org.lwjgl.system.MemoryUtil;
|
import org.lwjgl.system.MemoryUtil;
|
||||||
|
|
||||||
import speiger.src.collections.objects.maps.interfaces.Object2ObjectMap;
|
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.AssetLocation;
|
||||||
import speiger.src.coreengine.assets.base.IAsset;
|
import speiger.src.coreengine.assets.base.IAsset;
|
||||||
import speiger.src.coreengine.assets.base.IAssetProvider;
|
import speiger.src.coreengine.assets.base.IAssetProvider;
|
||||||
import speiger.src.coreengine.math.ArrayUtil;
|
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.rendering.utils.values.IGLValue.IShaderType;
|
||||||
import speiger.src.coreengine.utils.io.GameLog;
|
import speiger.src.coreengine.utils.io.GameLog;
|
||||||
|
|
||||||
public abstract class ShaderProgram {
|
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;
|
private int id;
|
||||||
|
|
||||||
public boolean isValid() { return id != 0; }
|
public boolean isValid() { return id != 0; }
|
||||||
public abstract boolean isActive();
|
public boolean isActive() { return GLStateTracker.SHADERS.isShaderActive(this); }
|
||||||
public int id() { return id; }
|
public int id() { return id; }
|
||||||
public abstract void bind();
|
public UniformManager getUniforms() { return uniforms; }
|
||||||
public abstract void unbind();
|
|
||||||
public abstract void remove();
|
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) {
|
public static int loadOrGenerateCache(String location, FileTime newestResource, IntPredicate callback) {
|
||||||
int id = GL20.glCreateProgram();
|
int id = GL20.glCreateProgram();
|
||||||
boolean fail = true;
|
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(GL46.glGetProgrami(id, GL46.GL_LINK_STATUS) == GL46.GL_TRUE) {
|
||||||
if(ShaderCache.INSTANCE.hasCache()) ShaderCache.INSTANCE.storeInCache(location, getProgramBytes(id));
|
if(ShaderCache.INSTANCE.hasCache()) ShaderCache.INSTANCE.storeInCache(location, getProgramBytes(id));
|
||||||
fail = false;
|
fail = false;
|
||||||
|
@ -69,10 +86,10 @@ public abstract class ShaderProgram {
|
||||||
for(String line : asset.lines()) {
|
for(String line : asset.lines()) {
|
||||||
if(line.startsWith("//")) continue;
|
if(line.startsWith("//")) continue;
|
||||||
if(line.startsWith("#import<") && line.endsWith(">")) {
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
builder.append(line).append("//\n");
|
builder.append(line).append("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Exception e) {
|
catch(Exception e) {
|
||||||
|
@ -97,7 +114,7 @@ public abstract class ShaderProgram {
|
||||||
StringBuilder builder = new StringBuilder();
|
StringBuilder builder = new StringBuilder();
|
||||||
for(String line : asset.lines()) {
|
for(String line : asset.lines()) {
|
||||||
if(line.startsWith("//")) continue;
|
if(line.startsWith("//")) continue;
|
||||||
builder.append(line).append("//\n");
|
builder.append(line).append("\n");
|
||||||
}
|
}
|
||||||
return builder.toString();
|
return builder.toString();
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,12 +10,16 @@ import speiger.src.coreengine.assets.base.IReloadableAsset.ISimpleRealodableAsse
|
||||||
|
|
||||||
public class ShaderTracker implements ISimpleRealodableAsset, IManagedAsset {
|
public class ShaderTracker implements ISimpleRealodableAsset, IManagedAsset {
|
||||||
ObjectList<Shader<?>> shaders = new ObjectArrayList<>();
|
ObjectList<Shader<?>> shaders = new ObjectArrayList<>();
|
||||||
int shader;
|
int activeShaderId;
|
||||||
IAssetProvider provider;
|
IAssetProvider provider;
|
||||||
|
|
||||||
public void registerShader(Shader<?> shader) {
|
public void register(Shader<?> shader) {
|
||||||
shaders.add(shader);
|
shaders.add(shader);
|
||||||
shader.load(provider);
|
load(provider, shader);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void remove(Shader<?> shader) {
|
||||||
|
shaders.remove(shader);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(ShaderProgram program) {
|
public void bind(ShaderProgram program) {
|
||||||
|
@ -23,19 +27,16 @@ public class ShaderTracker implements ISimpleRealodableAsset, IManagedAsset {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void bind(int shaderId) {
|
public void bind(int shaderId) {
|
||||||
if(shader == shaderId) return;
|
if(activeShaderId == shaderId) return;
|
||||||
shader = shaderId;
|
activeShaderId = shaderId;
|
||||||
GL20.glUseProgram(shaderId);
|
GL20.glUseProgram(shaderId);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unbind() {
|
public void unbind() { bind(0); }
|
||||||
if(shader == 0) return;
|
|
||||||
shader = 0;
|
|
||||||
GL20.glUseProgram(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isActive() { return shader != 0; }
|
public boolean isActive() { return activeShaderId != 0; }
|
||||||
public int getActiveShader() { return shader; }
|
public boolean isShaderActive(ShaderProgram program) { return activeShaderId == shaderId(program); }
|
||||||
|
public int getActiveShader() { return activeShaderId; }
|
||||||
|
|
||||||
private int shaderId(ShaderProgram program) {
|
private int shaderId(ShaderProgram program) {
|
||||||
return program == null ? 0 : program.id();
|
return program == null ? 0 : program.id();
|
||||||
|
@ -45,7 +46,7 @@ public class ShaderTracker implements ISimpleRealodableAsset, IManagedAsset {
|
||||||
public void destroy() {
|
public void destroy() {
|
||||||
shaders.forEach(Shader::remove);
|
shaders.forEach(Shader::remove);
|
||||||
shaders.clear();
|
shaders.clear();
|
||||||
shader = 0;
|
activeShaderId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -56,10 +57,11 @@ public class ShaderTracker implements ISimpleRealodableAsset, IManagedAsset {
|
||||||
public void onAssetsReloaded(IAssetProvider provider) {
|
public void onAssetsReloaded(IAssetProvider provider) {
|
||||||
ShaderProgram.IMPORTS.clear();
|
ShaderProgram.IMPORTS.clear();
|
||||||
shaders.forEach(provider, this::load);
|
shaders.forEach(provider, this::load);
|
||||||
shader = 0;
|
activeShaderId = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void load(IAssetProvider provider, Shader<?> shader) {
|
private void load(IAssetProvider provider, Shader<?> shader) {
|
||||||
shader.load(provider);
|
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;
|
import speiger.src.coreengine.rendering.shader.ShaderProgram;
|
||||||
|
|
||||||
public interface IUniform {
|
public interface IUniform {
|
||||||
|
public String getName();
|
||||||
public void registerShader(ShaderProgram program);
|
public void registerShader(ShaderProgram program);
|
||||||
public void removeShader(ShaderProgram program);
|
public void removeShader(ShaderProgram program);
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,6 +16,11 @@ public abstract class Uniform implements IUniform {
|
||||||
positions.setDefaultReturnValue(-1);
|
positions.setDefaultReturnValue(-1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
protected int getPosition(ShaderProgram program) {
|
protected int getPosition(ShaderProgram program) {
|
||||||
return positions.get(program.id());
|
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();
|
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) {
|
public Vec2fUniform set(Vec2f value) {
|
||||||
return set(value.x(), value.y());
|
return set(value.x(), value.y());
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,18 @@ public class Vec3fUniform extends Uniform {
|
||||||
this.value = value.asMutable();
|
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) {
|
public Vec3fUniform set(Vec3f value) {
|
||||||
return set(value.x(), value.y(), value.z());
|
return set(value.x(), value.y(), value.z());
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,22 @@ public class Vec4fUniform extends Uniform {
|
||||||
this.value = value.asMutable();
|
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) {
|
public Vec4fUniform set(Vec4f value) {
|
||||||
return set(value.x(), value.y(), value.z(), value.w());
|
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());
|
GL41.glProgramUniform4f(programId, location, value.x(), value.y(), value.z(), value.w());
|
||||||
AllocationTracker.INSTANCE.addGPUBytes(16L);
|
AllocationTracker.INSTANCE.addGPUBytes(16L);
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -87,7 +87,7 @@ public abstract class ShaderProgram
|
||||||
for(String s : IterableWrapper.wrap(asset.reader()))
|
for(String s : IterableWrapper.wrap(asset.reader()))
|
||||||
{
|
{
|
||||||
if(s.startsWith("//")) continue;
|
if(s.startsWith("//")) continue;
|
||||||
shaderSource.append(s).append("//\n");
|
shaderSource.append(s).append("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch(Exception e) {
|
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.ObjectArrayList;
|
||||||
import speiger.src.collections.objects.lists.ObjectList;
|
import speiger.src.collections.objects.lists.ObjectList;
|
||||||
import speiger.src.coreengine.rendering.shader.ShaderTracker;
|
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.BlendState;
|
||||||
import speiger.src.coreengine.rendering.utils.states.CullState;
|
import speiger.src.coreengine.rendering.utils.states.CullState;
|
||||||
import speiger.src.coreengine.rendering.utils.states.FloatState;
|
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 Counter[] COUNTERS = Counter.createCounters(4);
|
||||||
public static final ViewPortStack VIEW_PORT = new ViewPortStack();
|
public static final ViewPortStack VIEW_PORT = new ViewPortStack();
|
||||||
public static final ShaderTracker SHADERS = new ShaderTracker();
|
public static final ShaderTracker SHADERS = new ShaderTracker();
|
||||||
|
public static final GlobalUniforms UNIFORMS = new GlobalUniforms();
|
||||||
public static final TextureState TEXTURES = addState(new TextureState());
|
public static final TextureState TEXTURES = addState(new TextureState());
|
||||||
|
|
||||||
public static <T extends IGLState> T addState(T state) {
|
public static <T extends IGLState> T addState(T state) {
|
||||||
|
|
Loading…
Reference in New Issue