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…
Reference in New Issue