Reworked Shaders/Uniforms and started work on GuiComponents

This commit is contained in:
Speiger 2024-01-04 00:48:13 +01:00
parent 6091d8319a
commit c464aaa271
24 changed files with 361 additions and 58 deletions

View File

@ -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

View File

@ -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)
} }
} }

View File

@ -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

View File

@ -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);
} }

View File

@ -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();

View File

@ -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
} }
} }

View File

@ -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);

View File

@ -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);
}

View File

@ -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() {

View File

@ -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();

View File

@ -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);
} }

View File

@ -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; }
} }

View File

@ -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();
} }

View File

@ -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();
} }
} }

View File

@ -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();
}
}

View File

@ -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);
} }

View File

@ -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());
} }

View File

@ -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);
}
}
}

View File

@ -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);
}
}

View File

@ -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());
} }

View File

@ -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());
} }

View File

@ -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());
} }

View File

@ -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) {

View File

@ -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) {