More work on the GPU API

This commit is contained in:
Speiger 2026-05-28 13:31:16 +02:00
parent bc078abea4
commit c1f6c5ec10
27 changed files with 898 additions and 643 deletions

View File

@ -1,30 +1,30 @@
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="bin/main" path="src/main/java">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/main" path="src/main/resources">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/graphics" path="src/graphics/java">
<attributes>
<attribute name="gradle_scope" value="graphics"/>
<attribute name="gradle_used_by_scope" value="graphics"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/graphics" path="src/graphics/resources">
<attributes>
<attribute name="gradle_scope" value="graphics"/>
<attribute name="gradle_used_by_scope" value="graphics"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-25/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>
<?xml version="1.0" encoding="UTF-8"?>
<classpath>
<classpathentry kind="src" output="bin/main" path="src/main/java">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/main" path="src/main/resources">
<attributes>
<attribute name="gradle_scope" value="main"/>
<attribute name="gradle_used_by_scope" value="main,test"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/graphics" path="src/graphics/java">
<attributes>
<attribute name="gradle_scope" value="graphics"/>
<attribute name="gradle_used_by_scope" value="graphics"/>
</attributes>
</classpathentry>
<classpathentry kind="src" output="bin/graphics" path="src/graphics/resources">
<attributes>
<attribute name="gradle_scope" value="graphics"/>
<attribute name="gradle_used_by_scope" value="graphics"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-25/"/>
<classpathentry kind="con" path="org.eclipse.buildship.core.gradleclasspathcontainer"/>
<classpathentry kind="output" path="bin/default"/>
</classpath>

View File

@ -1,23 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>GameProject-SimpleJavaEngine</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
</projectDescription>
<?xml version="1.0" encoding="UTF-8"?>
<projectDescription>
<name>SimpleJavaEngine</name>
<comment></comment>
<projects>
</projects>
<buildSpec>
<buildCommand>
<name>org.eclipse.jdt.core.javabuilder</name>
<arguments>
</arguments>
</buildCommand>
<buildCommand>
<name>org.eclipse.buildship.core.gradleprojectbuilder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec>
<natures>
<nature>org.eclipse.jdt.core.javanature</nature>
<nature>org.eclipse.buildship.core.gradleprojectnature</nature>
</natures>
</projectDescription>

View File

@ -1,13 +1,13 @@
arguments=
auto.sync=false
build.scans.enabled=false
connection.gradle.distribution=GRADLE_DISTRIBUTION(VERSION(9.1.0))
connection.project.dir=
eclipse.preferences.version=1
gradle.user.home=
java.home=C\:/Program Files/Java/jdk-25.0.2+10
jvm.arguments=
offline.mode=false
override.workspace.settings=true
show.console.view=false
show.executions.view=false
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=C\:/Program Files/Java/jdk25
jvm.arguments=
offline.mode=false
override.workspace.settings=true
show.console.view=false
show.executions.view=false

View File

@ -7,10 +7,23 @@ tasks.withType(JavaCompile) {
options.encoding = 'UTF-8'
}
eclipse {
classpath {
downloadJavadoc = true
downloadSources = true
file {
whenMerged { cp ->
cp.entries.forEach { entry ->
// Target the core LWJGL modules
if (entry.kind == 'lib' && entry.path.contains('org.lwjgl')) {
// Dynamically add a JPMS modular export rule to the Eclipse compiler
def rule = new org.gradle.plugins.ide.eclipse.model.AccessRule('accessible', 'org/lwjgl/system/**')
entry.accessRules.add(rule)
}
}
}
}
}
}
@ -29,7 +42,7 @@ repositories {
name = "Speiger Maven"
url = "https://maven.speiger.com/repository/main"
}
maven { url "https://oss.sonatype.org/content/repositories/snapshots/" }
maven { url "https://central.sonatype.com/repository/maven-snapshots" }
}

View File

@ -1,4 +1,4 @@
org.gradle.jvmargs=-Xmx2G
lwjglVersion = 3.3.4
org.gradle.jvmargs=-Xmx2G
lwjglVersion = 3.3.4
lwjglNatives = natives-windows

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

View File

@ -1,5 +0,0 @@
package speiger.src.coreengine.api.buffer;
public interface VertexBuffer {
}

View File

@ -1,5 +0,0 @@
package speiger.src.coreengine.api.core;
public interface GraphicsCommandQueue {
}

View File

@ -1,5 +0,0 @@
package speiger.src.coreengine.api.core;
public interface GraphicsResource {
public void remove();
}

View File

@ -1,6 +0,0 @@
package speiger.src.coreengine.api.texture;
public abstract class Texture {
protected final TextureType type = null;
}

View File

@ -0,0 +1,13 @@
package speiger.src.coreengine.graphics.api.buffer;
public enum BufferState {
STATIC_DRAW,
STATIC_READ,
STATIC_COPY,
STREAM_DRAW,
STREAM_READ,
STREAM_COPY,
DYNAMIC_DRAW,
DYNAMIC_READ,
DYNAMIC_COPY;
}

View File

@ -0,0 +1,44 @@
package speiger.src.coreengine.graphics.api.buffer;
import java.nio.Buffer;
import java.nio.ByteBuffer;
import org.lwjgl.system.MemoryUtil;
import speiger.src.coreengine.graphics.api.core.GraphicsResource;
public abstract class VertexBuffer implements GraphicsResource {
protected final BufferState usage;
protected int size;
public VertexBuffer(BufferState usage, int size) {
this.usage = usage;
this.size = size;
}
public BufferState usage() {
return usage;
}
public int size() {
return size;
}
public abstract VertexBuffer allocate(int totalBytes);
public abstract VertexBuffer set(long pointer, int totalBytes);
public VertexBuffer set(ByteBuffer buffer) {
return set(MemoryUtil.memAddress(buffer), buffer.remaining());
}
public abstract VertexBuffer fill(long pointer, int totalBytes, int offset);
public VertexBuffer fill(int offset, ByteBuffer buffer) {
return fill(MemoryUtil.memAddress(buffer), buffer.remaining(), offset);
}
public abstract VertexBuffer read(long pointer, int totalbytes, int offset);
public VertexBuffer read(Buffer buffer, int totalBytes, int offset) {
return read(MemoryUtil.memAddress(buffer), totalBytes, offset);
}
}

View File

@ -1,9 +1,9 @@
package speiger.src.coreengine.api.core;
import speiger.src.coreengine.rendering.input.window.Window;
public interface Graphics {
public String getName();
public GraphicsDevice createDevice(Window window);
}
package speiger.src.coreengine.graphics.api.core;
import speiger.src.coreengine.rendering.input.window.Window;
public interface Graphics {
public String getName();
public GraphicsDevice createDevice(Window window);
}

View File

@ -0,0 +1,5 @@
package speiger.src.coreengine.graphics.api.core;
public interface GraphicsCommandQueue {
}

View File

@ -1,12 +1,12 @@
package speiger.src.coreengine.api.core;
import speiger.src.coreengine.api.buffer.VertexBuffer;
import speiger.src.coreengine.api.texture.Texture;
import speiger.src.coreengine.rendering.input.window.Window;
public interface GraphicsDevice {
public GraphicsSurface createSurface(Window window);
public GraphicsCommandQueue getQueue();
public VertexBuffer createBuffer();
public Texture createTexture();
}
package speiger.src.coreengine.graphics.api.core;
import speiger.src.coreengine.graphics.api.buffer.VertexBuffer;
import speiger.src.coreengine.graphics.api.texture.Texture;
import speiger.src.coreengine.rendering.input.window.Window;
public interface GraphicsDevice {
public GraphicsSurface createSurface(Window window);
public GraphicsCommandQueue getQueue();
public VertexBuffer createBuffer();
public Texture createTexture();
}

View File

@ -0,0 +1,11 @@
package speiger.src.coreengine.graphics.api.core;
public interface GraphicsResource extends AutoCloseable {
public boolean isRemoved();
public void remove();
@Override
default void close() {
remove();
}
}

View File

@ -1,5 +1,5 @@
package speiger.src.coreengine.api.core;
public interface GraphicsSurface {
public void setVsync(boolean value);
}
package speiger.src.coreengine.graphics.api.core;
public interface GraphicsSurface {
public void setVsync(boolean value);
}

View File

@ -0,0 +1,13 @@
package speiger.src.coreengine.graphics.api.sampler;
public abstract class Sampler {
SamplerSettings settings;
public Sampler(SamplerSettings settings) {
this.settings = settings;
}
public SamplerSettings settings() {
return settings;
}
}

View File

@ -0,0 +1,5 @@
package speiger.src.coreengine.graphics.api.sampler;
public class SamplerSettings {
}

View File

@ -0,0 +1,16 @@
package speiger.src.coreengine.graphics.api.texture;
import speiger.src.coreengine.graphics.api.core.GraphicsResource;
public abstract class Texture implements GraphicsResource {
final TextureSettings settings;
public Texture(TextureSettings settings) {
this.settings = settings;
}
public TextureSettings settings() {
return settings;
}
}

View File

@ -0,0 +1,128 @@
package speiger.src.coreengine.graphics.api.texture;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.OptionalInt;
import speiger.src.collections.objects.lists.ImmutableObjectList;
import speiger.src.coreengine.graphics.api.texture.states.StencilType;
import speiger.src.coreengine.graphics.api.texture.states.SwizzleMask;
import speiger.src.coreengine.graphics.api.texture.states.TextureFormat;
import speiger.src.coreengine.graphics.api.texture.states.TextureType;
public record TextureSettings(TextureType type, TextureFormat internal, TextureFormat external, boolean generateMipmapping, OptionalInt baseLevel, OptionalInt maxLevel, List<Optional<SwizzleMask>> swizzle, Optional<StencilType> stencilType) {
public Builder copy() { return new Builder(this); }
public static Builder builder() { return new Builder(); }
public boolean hasSwizzle() {
for(int i = 0;i<4;i++) {
if(swizzle().get(i).isPresent()) return true;
}
return false;
}
public static class Builder {
TextureFormat internalFormat;
TextureFormat externalFormat;
TextureType type;
boolean generateMipmapping = false;
OptionalInt baseLevel = OptionalInt.empty();
OptionalInt maxLevel = OptionalInt.empty();
@SuppressWarnings("unchecked")
Optional<SwizzleMask>[] swizzle = new Optional[] {Optional.empty(), Optional.empty(), Optional.empty(), Optional.empty()};
Optional<StencilType> stencilType = Optional.empty();
private Builder() {}
private Builder(TextureSettings settings) {
type = settings.type;
internalFormat = settings.internal;
externalFormat = settings.external;
generateMipmapping = settings.generateMipmapping;
baseLevel = settings.baseLevel;
maxLevel = settings.maxLevel;
settings.swizzle.toArray(swizzle);
stencilType = settings.stencilType;
}
public TextureSettings build() {
return new TextureSettings(
Objects.requireNonNull(type, "Texture Type shouldn't be null"),
Objects.requireNonNull(internalFormat, "Internal Format shouldn't be null"),
Objects.requireNonNull(externalFormat, "External Format shouldn't be null"),
generateMipmapping, baseLevel, maxLevel, new ImmutableObjectList<>(swizzle), stencilType);
}
public Builder type(TextureType type) {
this.type = type;
return this;
}
public Builder format(TextureFormat format) {
this.internalFormat = format;
this.externalFormat = format;
return this;
}
public Builder internal(TextureFormat format) {
this.internalFormat = format;
return this;
}
public Builder external(TextureFormat format) {
this.externalFormat = format;
return this;
}
public Builder swizzle(SwizzleMask red, SwizzleMask green, SwizzleMask blue, SwizzleMask alpha) {
swizzle[0] = Optional.ofNullable(red);
swizzle[1] = Optional.ofNullable(green);
swizzle[2] = Optional.ofNullable(blue);
swizzle[3] = Optional.ofNullable(alpha);
return this;
}
public Builder swizzleRed(SwizzleMask mask) {
swizzle[0] = Optional.ofNullable(mask);
return this;
}
public Builder swizzleGreen(SwizzleMask mask) {
swizzle[1] = Optional.ofNullable(mask);
return this;
}
public Builder swizzleBlue(SwizzleMask mask) {
swizzle[2] = Optional.ofNullable(mask);
return this;
}
public Builder swizzleAlpha(SwizzleMask mask) {
swizzle[3] = Optional.ofNullable(mask);
return this;
}
public Builder stencil(StencilType type) {
stencilType = Optional.ofNullable(type);
return this;
}
public Builder generateMipmapping(boolean value) {
this.generateMipmapping = value;
return this;
}
public Builder mipMapping(int base, int max) {
this.baseLevel = OptionalInt.of(base);
this.maxLevel = OptionalInt.of(max);
return this;
}
public Builder clearmMipMapping() {
this.baseLevel = OptionalInt.empty();
this.maxLevel = OptionalInt.empty();
return this;
}
}
}

View File

@ -0,0 +1,6 @@
package speiger.src.coreengine.graphics.api.texture.states;
public enum StencilType {
DEPTH_COMPONENT,
STENCIL_INDEX
}

View File

@ -0,0 +1,10 @@
package speiger.src.coreengine.graphics.api.texture.states;
public enum SwizzleMask {
ZERO,
ONE,
RED,
GREEN,
BLUE,
ALPHA;
}

View File

@ -0,0 +1,11 @@
package speiger.src.coreengine.graphics.api.texture.states;
public enum TextureFormat {
R,
RGB,
RGBA,
DEPTH,
DEPTH_STENCIL,
LUMINANCE,
LUMINANCE_ALPHA
}

View File

@ -1,15 +1,15 @@
package speiger.src.coreengine.api.texture;
public enum TextureType {
TEXTURE_1D,
TEXTURE_1D_ARRAY,
TEXTURE_2D,
TEXTURE_2D_ARRAY,
TEXTURE_2D_MULTISAMPLE,
TEXTURE_2D_MULTISAMPLE_ARRAY,
TEXTURE_3D,
TEXTURE_CUBE_MAP,
TEXTURE_CUBE_MAP_ARRAY,
TEXTURE_RECTANGLE,
TEXTURE_BUFFER;
}
package speiger.src.coreengine.graphics.api.texture.states;
public enum TextureType {
TEXTURE_1D,
TEXTURE_1D_ARRAY,
TEXTURE_2D,
TEXTURE_2D_ARRAY,
TEXTURE_2D_MULTISAMPLE,
TEXTURE_2D_MULTISAMPLE_ARRAY,
TEXTURE_3D,
TEXTURE_CUBE_MAP,
TEXTURE_CUBE_MAP_ARRAY,
TEXTURE_RECTANGLE,
TEXTURE_BUFFER;
}

View File

@ -1,324 +1,325 @@
package speiger.src.coreengine;
import java.util.List;
import java.util.function.BiConsumer;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL43;
import org.lwjgl.system.Configuration;
import org.lwjgl.util.freetype.FreeType;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.assets.AssetLocation;
import speiger.src.coreengine.assets.AssetManager;
import speiger.src.coreengine.assets.base.IAssetPackage;
import speiger.src.coreengine.assets.base.IAssetProvider;
import speiger.src.coreengine.math.vector.matrix.Matrix4f;
import speiger.src.coreengine.rendering.gui.font.Font;
import speiger.src.coreengine.rendering.gui.font.FontManager;
import speiger.src.coreengine.rendering.gui.font.TextStyle;
import speiger.src.coreengine.rendering.gui.font.glyth.Glyth;
import speiger.src.coreengine.rendering.gui.font.glyth.IGlythSheetInfo;
import speiger.src.coreengine.rendering.gui.font.glyth.MissingGlyth;
import speiger.src.coreengine.rendering.gui.font.glyth.UnbakedGlyth.GlythBaker;
import speiger.src.coreengine.rendering.input.devices.FileDrop;
import speiger.src.coreengine.rendering.input.devices.Joystick;
import speiger.src.coreengine.rendering.input.devices.Keyboard;
import speiger.src.coreengine.rendering.input.devices.Mouse;
import speiger.src.coreengine.rendering.input.events.KeyEvent;
import speiger.src.coreengine.rendering.input.events.MouseEvent;
import speiger.src.coreengine.rendering.input.window.Window;
import speiger.src.coreengine.rendering.input.window.WindowManager;
import speiger.src.coreengine.rendering.models.buffers.BufferAttribute;
import speiger.src.coreengine.rendering.models.buffers.VertexArray;
import speiger.src.coreengine.rendering.shader.Shader;
import speiger.src.coreengine.rendering.shader.SimpleShader;
import speiger.src.coreengine.rendering.shader.uniform.base.TextureUniform;
import speiger.src.coreengine.rendering.shader.uniform.vec.Matrix4fUniform;
import speiger.src.coreengine.rendering.tesselation.buffer.IVertexBuilder;
import speiger.src.coreengine.rendering.tesselation.buffer.VertexBuilder;
import speiger.src.coreengine.rendering.tesselation.format.VertexTypes;
import speiger.src.coreengine.rendering.textures.custom.Drawable;
import speiger.src.coreengine.rendering.textures.custom.DynamicTexture;
import speiger.src.coreengine.rendering.utils.GLStateTracker;
import speiger.src.coreengine.rendering.utils.values.GLDataType;
import speiger.src.coreengine.rendering.utils.values.GLMode;
import speiger.src.coreengine.rendering.utils.values.textures.GLTextureFormat;
import speiger.src.coreengine.utils.eventbus.EventBus;
import speiger.src.coreengine.utils.helpers.IOUtils;
public class NewInputTest {
EventBus bus = new EventBus();
WindowManager manager = new WindowManager();
AssetManager assets = new AssetManager(List.of(IAssetPackage.of(IOUtils.getBaseLocation())));
FontManager fonts = new FontManager();
private Shader<TestShader> shaderTest = Shader.create(TestShader::new);
private Shader<GuiShader> guiShader = Shader.create(GuiShader::new);
public static void main(String[] args) {
new NewInputTest().run();
}
private void applyWindowSize(Window window) {
int scale = 0;
guiShader.get().proView.set(new Matrix4f().ortho(0, 0, window.width() >> scale, window.height() >> scale, 1000, -1000));
}
public void run() {
Configuration.HARFBUZZ_LIBRARY_NAME.set(FreeType.getLibrary());
GLFW.glfwInit();
manager.initialize();
Mouse.INSTANCE.init(bus);
Keyboard.INSTANCE.init(bus);
Joystick.INSTANCE.init(manager, bus);
FileDrop.INSTANCE.init(bus);
manager.addDevices(Mouse.INSTANCE, Keyboard.INSTANCE, Joystick.INSTANCE, FileDrop.INSTANCE);
Window window = manager.builder().title("Testing Engine").width(800).height(600).antialis(0).build();
Window secondWindow = manager.builder().title("Second Window Engine").width(800).height(600).antialis(0).build();
Thread.ofPlatform().start(() -> drawSecondScreen(secondWindow));
window.setupContext();
shaderTest.register();
guiShader.register();
assets.addListener(GLStateTracker.instance().shaders);
assets.addListener(GLStateTracker.TEXTURE_TRACKER);
assets.addListener(fonts);
assets.reload();
applyWindowSize(window);
System.out.println("Testing: "+GL.getCapabilities().OpenGL41);
System.out.println("Testing: "+Integer.divideUnsigned(-1, 255));
GL11.glEnable(GL43.GL_MULTISAMPLE);
int size = 512;
int half = size >> 1;
int base = size >> 3;
DynamicTexture texture = new DynamicTexture(size, size, DynamicTexture.DEFAULT_PARAMETERS);
texture.fill(0, 0, size, size, -1);
texture.fill(0, 0, half, half, 255, 0, 0, 255);
texture.fill(half, 0, half, half, 0, 255, 0, 255);
texture.fill(half, half, half, half, 255, 0, 0, 255);
texture.fill(0, half, half, half, 0, 0, 255, 255);
texture.process(true);
window.visible(true);
bus.register(MouseEvent.Click.class, T -> {
System.out.println("Testing: Button="+T.button()+", Click="+T.press()+", X="+T.x()+", Y="+T.y()+", WindowId="+T.windowId()+", WindowName="+manager.getWindow(T.windowId()).title());
});
bus.register(KeyEvent.Key.class, T -> {
if(T.key() == GLFW.GLFW_KEY_T) {
T.cancel();
// texture.bind();
Drawable drawable = new Drawable(GLTextureFormat.RGBA, half, half);
drawable.fill(0, 0, half, half, 255, 255, 0, 255);
drawable.upload(texture.id(), base * 3, base * 3, base, base, base * 2, base * 2);
drawable.close();
}
else if(T.key() == GLFW.GLFW_KEY_U) {
MissingGlyth glyth = new MissingGlyth(18.5F, 4F);
glyth.bake(new GlythBaker() {
@Override
public Glyth bake(IGlythSheetInfo info) {
int width = info.width();
int height = info.height();
info.upload(texture.id(), half - (width >> 1), half - (height >> 1));
System.out.println("Test3: "+width+", "+height);
return null;
}
});
}
else if(T.key() == GLFW.GLFW_KEY_O && T.press()) {
window.borderless(!window.isBorderless());
}
});
VertexBuilder builder = new VertexBuilder(255);
builder.start(GLMode.TRIANGLES, VertexTypes.TESTING);
builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1).endVertex();
builder.pos(0.5F, -0.5F, 0).tex(1F, 1F).rgba(-1).endVertex();
builder.pos(0.5F, 0.5F, 0).tex(1F, 0F).rgba(-1).endVertex();
builder.pos(0.5F, 0.5F, 0).tex(1F, 0F).rgba(-1).endVertex();
builder.pos(-0.5F, 0.5F, 0).tex(0F, 0F).rgba(-1).endVertex();
builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1).endVertex();
// Font font = fonts.createFont(1F);
TestModel model = new TestModel(builder.getBytes());
// TestModel[] guiModel = new TestModel[1];
// List<GLDraw> draws = new ObjectArrayList<>();
// TexturedBuffer buffer = new TexturedBuffer((K, V) -> {
// draws.addAll(K);
// guiModel[0] = new TestModel(V);
// System.out.println("Testing: "+V.length+" bytes, "+K.size());
// });
// String s = "The Quick brown fox Jumps over the Lazy dog";
float x = 50;
float y = 50;
float scale = 1F;
y /= scale;
TextStyle style = TextStyle.DEFAULT.size(12).bold(false);
// font.drawText(style, "Testing My Theory", x, y, -1, buffer, scale, true);
// float offset = font.drawText(style, "The Quick ", 50, y, -1, buffer, scale, false);
// offset += font.drawText(style, "Brown ", 50+offset, y, -1, buffer, scale, false);
// offset += font.drawText(style, "§<c=0x24FF00FF>F§<c=r>ox ", 50+offset, y, -1, buffer, scale, false);
// offset += font.drawText(style, "Jumps ", 50+offset, y, -1, buffer, scale, false);
// offset += font.drawText(style, "over the Lazy dog", 50+offset, y, -1, buffer, scale, true);
// font.drawText(s, 50, 50, -1, buffer, true);
GLStateTracker tracker = GLStateTracker.instance();
GL11.glClearColor(0.2F, 0.55F, 0.66F, 1F);
while(!window.shouldClose()) {
GLFW.glfwPollEvents();
if(window.changed()) {
window.updateViewport();
applyWindowSize(window);
}
window.beginFrame();
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
texture.bind();
shaderTest.bind();
model.bindArray();
GLStateTracker.drawArrays(GLMode.TRIANGLES.glValue(), 6);
model.unbindArray();
// guiModel[0].bindArray();
// guiShader.bind();
// tracker.blend.enable();
// tracker.blend.setFunction(GLBlendFactor.SRC_ALPHA, GLBlendFactor.ONE_MINUS_SRC_ALPHA);
// for(GLDraw draw : draws) {
// tracker.textures.bind(draw.texture());
// GLStateTracker.drawArrays(GLMode.TRIANGLES.glValue(), draw.startVertex(), draw.vertexCount());
// }
// GLStateTracker.instance().blend.disable();
// guiModel[0].unbindArray();
window.handleInput();
window.finishFrame();
try { Thread.sleep(100); }
catch(InterruptedException e) { e.printStackTrace(); }
}
window.destroy();
manager.destroy();
}
public void drawSecondScreen(Window window) {
window.setupContext();
assets.addListener(GLStateTracker.instance().shaders);
Shader<TestShader> secondShader = Shader.createAndRegister(TestShader::new);
guiShader.register();
window.visible(true);
GL11.glClearColor(0.4F, 0.55F, 0.36F, 1F);
int size = 512;
int half = size >> 1;
int base = size >> 3;
DynamicTexture texture = new DynamicTexture(size, size, DynamicTexture.DEFAULT_PARAMETERS);
texture.fill(0, 0, size, size, -1);
texture.fill(0, 0, half, half, 255, 0, 0, 255);
texture.fill(half, 0, half, half, 0, 255, 0, 255);
texture.fill(half, half, half, half, 255, 0, 0, 255);
texture.fill(0, half, half, half, 0, 0, 255, 255);
texture.process(true);
VertexBuilder builder = new VertexBuilder(255);
builder.start(GLMode.TRIANGLES, VertexTypes.TESTING);
builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1).endVertex();
builder.pos(0.5F, -0.5F, 0).tex(1F, 1F).rgba(-1).endVertex();
builder.pos(0.5F, 0.5F, 0).tex(1F, 0F).rgba(-1).endVertex();
builder.pos(0.5F, 0.5F, 0).tex(1F, 0F).rgba(-1).endVertex();
builder.pos(-0.5F, 0.5F, 0).tex(0F, 0F).rgba(-1).endVertex();
builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1).endVertex();
TestModel model = new TestModel(builder.getBytes());
while(!window.shouldClose()) {
GLFW.glfwPollEvents();
if(window.changed()) {
window.updateViewport();
applyWindowSize(window);
}
window.beginFrame();
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
texture.bind();
secondShader.bind();
model.bindArray();
GLStateTracker.drawArrays(GLMode.TRIANGLES.glValue(), 6);
model.unbindArray();
window.handleInput();
window.finishFrame();
try { Thread.sleep(100); }
catch(InterruptedException e) { e.printStackTrace(); }
}
window.destroy();
}
public static class TexturedBuffer implements Font.TexturedBuffer {
int previousId = -1;
int lastVertex = 0;
List<GLDraw> draws = new ObjectArrayList<>();
VertexBuilder builder;
BiConsumer<List<GLDraw>, byte[]> callbacks;
public TexturedBuffer(BiConsumer<List<GLDraw>, byte[]> callbacks) {
this.callbacks = callbacks;
}
@Override
public IVertexBuilder builderForTexture(int textureId) {
if(builder == null) {
builder = new VertexBuilder(100000);
builder.start(GLMode.TRIANGLES, VertexTypes.TESTING);
previousId = textureId;
}
else if(previousId != textureId) {
int count = builder.size() - lastVertex;
draws.add(new GLDraw(previousId, lastVertex, count));
lastVertex+=count;
previousId = textureId;
}
return builder;
}
@Override
public void end() {
int count = builder.size() - lastVertex;
draws.add(new GLDraw(previousId, lastVertex, count));
callbacks.accept(draws, builder.getBytes());
builder.close();
}
}
public static record GLDraw(int texture, int startVertex, int vertexCount) {
}
public static class GuiShader extends SimpleShader {
public TextureUniform texture = uniforms.addTexture("texture", 0);
public Matrix4fUniform proView = uniforms.addMat("proViewMatrix", new Matrix4f());
public GuiShader(IAssetProvider provider) {
super(provider, "gui_shader", AssetLocation.of("shader/testGui/vertex.vs"), AssetLocation.of("shader/testGui/fragment.fs"), "in_position", "in_tex", "in_color");
}
}
public static class TestShader extends SimpleShader {
public TextureUniform texture = uniforms.addTexture("texture", 0);
public TestShader(IAssetProvider provider) {
super(provider, "testing_shader", AssetLocation.of("shader/testing/vertex.vs"), AssetLocation.of("shader/testing/fragment.fs"), "in_position", "in_tex", "in_color");
}
}
public static class TestModel extends VertexArray {
public TestModel(byte[] data) {
bind();
createBuffer(new BufferAttribute(0, 3), new BufferAttribute(1, 2), new BufferAttribute(2, 4, GLDataType.UNSIGNED_BYTE, true)).set(data).unbind();
unbind();
}
}
}
package speiger.src.coreengine;
import java.util.List;
import java.util.function.BiConsumer;
import org.lwjgl.glfw.GLFW;
import org.lwjgl.opengl.GL;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL43;
import org.lwjgl.system.Configuration;
import org.lwjgl.util.freetype.FreeType;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.assets.AssetLocation;
import speiger.src.coreengine.assets.AssetManager;
import speiger.src.coreengine.assets.base.IAssetPackage;
import speiger.src.coreengine.assets.base.IAssetProvider;
import speiger.src.coreengine.math.vector.matrix.Matrix4f;
import speiger.src.coreengine.rendering.gui.font.Font;
import speiger.src.coreengine.rendering.gui.font.FontManager;
import speiger.src.coreengine.rendering.gui.font.TextStyle;
import speiger.src.coreengine.rendering.gui.font.glyth.Glyth;
import speiger.src.coreengine.rendering.gui.font.glyth.IGlythSheetInfo;
import speiger.src.coreengine.rendering.gui.font.glyth.MissingGlyth;
import speiger.src.coreengine.rendering.gui.font.glyth.UnbakedGlyth.GlythBaker;
import speiger.src.coreengine.rendering.input.devices.FileDrop;
import speiger.src.coreengine.rendering.input.devices.Joystick;
import speiger.src.coreengine.rendering.input.devices.Keyboard;
import speiger.src.coreengine.rendering.input.devices.Mouse;
import speiger.src.coreengine.rendering.input.events.KeyEvent;
import speiger.src.coreengine.rendering.input.events.MouseEvent;
import speiger.src.coreengine.rendering.input.window.Window;
import speiger.src.coreengine.rendering.input.window.WindowManager;
import speiger.src.coreengine.rendering.models.buffers.BufferAttribute;
import speiger.src.coreengine.rendering.models.buffers.VertexArray;
import speiger.src.coreengine.rendering.shader.Shader;
import speiger.src.coreengine.rendering.shader.SimpleShader;
import speiger.src.coreengine.rendering.shader.uniform.base.TextureUniform;
import speiger.src.coreengine.rendering.shader.uniform.vec.Matrix4fUniform;
import speiger.src.coreengine.rendering.tesselation.buffer.IVertexBuilder;
import speiger.src.coreengine.rendering.tesselation.buffer.VertexBuilder;
import speiger.src.coreengine.rendering.tesselation.format.VertexTypes;
import speiger.src.coreengine.rendering.textures.custom.Drawable;
import speiger.src.coreengine.rendering.textures.custom.DynamicTexture;
import speiger.src.coreengine.rendering.utils.GLStateTracker;
import speiger.src.coreengine.rendering.utils.values.GLDataType;
import speiger.src.coreengine.rendering.utils.values.GLMode;
import speiger.src.coreengine.rendering.utils.values.textures.GLTextureFormat;
import speiger.src.coreengine.utils.eventbus.EventBus;
import speiger.src.coreengine.utils.helpers.IOUtils;
public class NewInputTest {
EventBus bus = new EventBus();
WindowManager manager = new WindowManager();
AssetManager assets = new AssetManager(List.of(IAssetPackage.of(IOUtils.getBaseLocation())));
FontManager fonts = new FontManager();
private Shader<TestShader> shaderTest = Shader.create(TestShader::new);
private Shader<GuiShader> guiShader = Shader.create(GuiShader::new);
public static void main(String[] args) {
new NewInputTest().run();
}
private void applyWindowSize(Window window) {
int scale = 0;
guiShader.get().proView.set(new Matrix4f().ortho(0, 0, window.width() >> scale, window.height() >> scale, 1000, -1000));
}
public void run() {
Configuration.HARFBUZZ_LIBRARY_NAME.set(FreeType.getLibrary());
GLFW.glfwInit();
manager.initialize();
Mouse.INSTANCE.init(bus);
Keyboard.INSTANCE.init(bus);
Joystick.INSTANCE.init(manager, bus);
FileDrop.INSTANCE.init(bus);
manager.addDevices(Mouse.INSTANCE, Keyboard.INSTANCE, Joystick.INSTANCE, FileDrop.INSTANCE);
Window window = manager.builder().title("Testing Engine").width(800).height(600).antialis(0).build();
Window secondWindow = manager.builder().title("Second Window Engine").width(800).height(600).antialis(0).build();
Thread.ofPlatform().start(() -> drawSecondScreen(secondWindow));
window.setupContext();
shaderTest.register();
guiShader.register();
assets.addListener(GLStateTracker.instance().shaders);
assets.addListener(GLStateTracker.TEXTURE_TRACKER);
assets.addListener(fonts);
assets.reload();
applyWindowSize(window);
System.out.println("Testing: "+GL.getCapabilities().OpenGL41);
System.out.println("Testing: "+Integer.divideUnsigned(-1, 255));
GL11.glEnable(GL43.GL_MULTISAMPLE);
int size = 512;
int half = size >> 1;
int base = size >> 3;
DynamicTexture texture = new DynamicTexture(size, size, DynamicTexture.DEFAULT_PARAMETERS);
texture.fill(0, 0, size, size, -1);
texture.fill(0, 0, half, half, 255, 0, 0, 255);
texture.fill(half, 0, half, half, 0, 255, 0, 255);
texture.fill(half, half, half, half, 255, 0, 0, 255);
texture.fill(0, half, half, half, 0, 0, 255, 255);
texture.process(true);
window.visible(true);
bus.register(MouseEvent.Click.class, T -> {
System.out.println("Testing: Button="+T.button()+", Click="+T.press()+", X="+T.x()+", Y="+T.y()+", WindowId="+T.windowId()+", WindowName="+manager.getWindow(T.windowId()).title());
});
bus.register(KeyEvent.Key.class, T -> {
if(T.key() == GLFW.GLFW_KEY_T) {
T.cancel();
// texture.bind();
Drawable drawable = new Drawable(GLTextureFormat.RGBA, half, half);
drawable.fill(0, 0, half, half, 255, 255, 0, 255);
drawable.upload(texture.id(), base * 3, base * 3, base, base, base * 2, base * 2);
drawable.close();
}
else if(T.key() == GLFW.GLFW_KEY_U) {
MissingGlyth glyth = new MissingGlyth(18.5F, 4F);
glyth.bake(new GlythBaker() {
@Override
public Glyth bake(IGlythSheetInfo info) {
int width = info.width();
int height = info.height();
info.upload(texture.id(), half - (width >> 1), half - (height >> 1));
System.out.println("Test3: "+width+", "+height);
return null;
}
});
}
else if(T.key() == GLFW.GLFW_KEY_O && T.press()) {
window.borderless(!window.isBorderless());
}
});
VertexBuilder builder = new VertexBuilder(255);
builder.start(GLMode.TRIANGLES, VertexTypes.TESTING);
builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1).endVertex();
builder.pos(0.5F, -0.5F, 0).tex(1F, 1F).rgba(-1).endVertex();
builder.pos(0.5F, 0.5F, 0).tex(1F, 0F).rgba(-1).endVertex();
builder.pos(0.5F, 0.5F, 0).tex(1F, 0F).rgba(-1).endVertex();
builder.pos(-0.5F, 0.5F, 0).tex(0F, 0F).rgba(-1).endVertex();
builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1).endVertex();
// Font font = fonts.createFont(1F);
TestModel model = new TestModel(builder.getBytes());
// TestModel[] guiModel = new TestModel[1];
// List<GLDraw> draws = new ObjectArrayList<>();
// TexturedBuffer buffer = new TexturedBuffer((K, V) -> {
// draws.addAll(K);
// guiModel[0] = new TestModel(V);
// System.out.println("Testing: "+V.length+" bytes, "+K.size());
// });
// String s = "The Quick brown fox Jumps over the Lazy dog";
float x = 50;
float y = 50;
float scale = 1F;
y /= scale;
TextStyle style = TextStyle.DEFAULT.size(12).bold(false);
// font.drawText(style, "Testing My Theory", x, y, -1, buffer, scale, true);
// float offset = font.drawText(style, "The Quick ", 50, y, -1, buffer, scale, false);
// offset += font.drawText(style, "Brown ", 50+offset, y, -1, buffer, scale, false);
// offset += font.drawText(style, "§<c=0x24FF00FF>F§<c=r>ox ", 50+offset, y, -1, buffer, scale, false);
// offset += font.drawText(style, "Jumps ", 50+offset, y, -1, buffer, scale, false);
// offset += font.drawText(style, "over the Lazy dog", 50+offset, y, -1, buffer, scale, true);
// font.drawText(s, 50, 50, -1, buffer, true);
GLStateTracker tracker = GLStateTracker.instance();
GL11.glClearColor(0.2F, 0.55F, 0.66F, 1F);
while(!window.shouldClose()) {
GLFW.glfwPollEvents();
if(window.changed()) {
window.updateViewport();
applyWindowSize(window);
}
window.beginFrame();
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
texture.bind();
shaderTest.bind();
model.bindArray();
GLStateTracker.drawArrays(GLMode.TRIANGLES.glValue(), 6);
model.unbindArray();
// guiModel[0].bindArray();
// guiShader.bind();
// tracker.blend.enable();
// tracker.blend.setFunction(GLBlendFactor.SRC_ALPHA, GLBlendFactor.ONE_MINUS_SRC_ALPHA);
// for(GLDraw draw : draws) {
// tracker.textures.bind(draw.texture());
// GLStateTracker.drawArrays(GLMode.TRIANGLES.glValue(), draw.startVertex(), draw.vertexCount());
// }
// GLStateTracker.instance().blend.disable();
// guiModel[0].unbindArray();
window.handleInput();
window.finishFrame();
try { Thread.sleep(100); }
catch(InterruptedException e) { e.printStackTrace(); }
}
window.destroy();
manager.destroy();
}
public void drawSecondScreen(Window window) {
window.setupContext();
assets.addListener(GLStateTracker.instance().shaders);
Shader<TestShader> secondShader = Shader.createAndRegister(TestShader::new);
guiShader.register();
window.visible(true);
GL11.glClearColor(0.4F, 0.55F, 0.36F, 1F);
int size = 512;
int half = size >> 1;
int base = size >> 3;
DynamicTexture texture = new DynamicTexture(size, size, DynamicTexture.DEFAULT_PARAMETERS);
texture.fill(0, 0, size, size, -1);
texture.fill(0, 0, half, half, 255, 0, 0, 255);
texture.fill(half, 0, half, half, 0, 255, 0, 255);
texture.fill(half, half, half, half, 255, 0, 0, 255);
texture.fill(0, half, half, half, 0, 0, 255, 255);
texture.process(true);
VertexBuilder builder = new VertexBuilder(255);
builder.start(GLMode.TRIANGLES, VertexTypes.TESTING);
builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1).endVertex();
builder.pos(0.5F, -0.5F, 0).tex(1F, 1F).rgba(-1).endVertex();
builder.pos(0.5F, 0.5F, 0).tex(1F, 0F).rgba(-1).endVertex();
builder.pos(0.5F, 0.5F, 0).tex(1F, 0F).rgba(-1).endVertex();
builder.pos(-0.5F, 0.5F, 0).tex(0F, 0F).rgba(-1).endVertex();
builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1).endVertex();
TestModel model = new TestModel(builder.getBytes());
while(!window.shouldClose()) {
GLFW.glfwPollEvents();
if(window.changed()) {
window.updateViewport();
applyWindowSize(window);
}
window.beginFrame();
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
texture.bind();
secondShader.bind();
model.bindArray();
GLStateTracker.drawArrays(GLMode.TRIANGLES.glValue(), 6);
model.unbindArray();
window.handleInput();
window.finishFrame();
try { Thread.sleep(100); }
catch(InterruptedException e) { e.printStackTrace(); }
}
window.destroy();
}
public static class TexturedBuffer implements Font.TexturedBuffer {
int previousId = -1;
int lastVertex = 0;
List<GLDraw> draws = new ObjectArrayList<>();
VertexBuilder builder;
BiConsumer<List<GLDraw>, byte[]> callbacks;
public TexturedBuffer(BiConsumer<List<GLDraw>, byte[]> callbacks) {
this.callbacks = callbacks;
}
@Override
public IVertexBuilder builderForTexture(int textureId) {
if(builder == null) {
builder = new VertexBuilder(100000);
builder.start(GLMode.TRIANGLES, VertexTypes.TESTING);
previousId = textureId;
}
else if(previousId != textureId) {
int count = builder.size() - lastVertex;
draws.add(new GLDraw(previousId, lastVertex, count));
lastVertex+=count;
previousId = textureId;
}
return builder;
}
@Override
public void end() {
int count = builder.size() - lastVertex;
draws.add(new GLDraw(previousId, lastVertex, count));
callbacks.accept(draws, builder.getBytes());
builder.close();
}
}
public static record GLDraw(int texture, int startVertex, int vertexCount) {
}
public static class GuiShader extends SimpleShader {
public TextureUniform texture = uniforms.addTexture("texture", 0);
public Matrix4fUniform proView = uniforms.addMat("proViewMatrix", new Matrix4f());
public GuiShader(IAssetProvider provider) {
super(provider, "gui_shader", AssetLocation.of("shader/testGui/vertex.vs"), AssetLocation.of("shader/testGui/fragment.fs"), "in_position", "in_tex", "in_color");
}
}
public static class TestShader extends SimpleShader {
public TextureUniform texture = uniforms.addTexture("texture", 0);
public TestShader(IAssetProvider provider) {
super(provider, "testing_shader", AssetLocation.of("shader/testing/vertex.vs"), AssetLocation.of("shader/testing/fragment.fs"), "in_position", "in_tex", "in_color");
}
}
public static class TestModel extends VertexArray {
public TestModel(byte[] data) {
bind();
createBuffer(new BufferAttribute(0, 3), new BufferAttribute(1, 2), new BufferAttribute(2, 4, GLDataType.UNSIGNED_BYTE, true)).set(data).unbind();
unbind();
}
}
}

View File

@ -1,182 +1,182 @@
package speiger.src.coreengine.rendering.guiOld.helper.box;
import java.util.List;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList;
public class GuiBox implements IGuiBox
{
ObjectList<IGuiBox> children = new ObjectArrayList<>();
IGuiBox parent;
float minX;
float minY;
float maxX;
float maxY;
float width;
float height;
float scale = 1F;
float baseX;
float baseY;
float baseWidth;
float baseHeight;
float baseScale = 1F;
protected GuiBox() {}
public GuiBox(float x, float y, float width, float height) {
set(x, y, width, height);
onChanged();
}
public static IGuiBox clone(IGuiBox box) {
return new GuiBox(box.getMinX(), box.getMinY(), box.getWidth(), box.getHeight());
}
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);
}
@Override
public IGuiBox addChild(IGuiBox box) {
children.add(box);
box.setParent(this);
return this;
}
@Override
public IGuiBox removeChild(IGuiBox box) {
if(children.remove(box)) box.setParent(null);
return this;
}
@Override
public IGuiBox clearChildren() {
for(int i = 0,m=children.size();i<m;i++) {
children.get(i).setParent(null);
}
children.clear();
return this;
}
@Override
public List<IGuiBox> children() {
return children.unmodifiable();
}
@Override
public IGuiBox onChanged() {
minX = parent == null ? baseX : parent.getMinX(baseX);
minY = parent == null ? baseY : parent.getMinY(baseY);
maxX = parent == null ? baseX + width : parent.getMinX(baseX + width);
maxY = parent == null ? baseY + height : parent.getMinY(baseY + height);
scale = parent == null ? baseScale : parent.getScale() * baseScale;
for(int i = 0,m=children.size();i<m;i++) {
children.get(i).onChanged();
}
return this;
}
@Override
public IGuiBox setParent(IGuiBox box) {
parent = box;
return this;
}
@Override
public IGuiBox getParent() { return parent; }
@Override
public float getScale() { return scale; }
@Override
public float getBaseX() { return baseX; }
@Override
public float getBaseY() { return baseY; }
@Override
public float getRelativeX() { return parent != null ? baseX : 0F; }
@Override
public float getRelativeY() { return parent != null ? baseY : 0F; }
@Override
public float getWidth() { return baseWidth * scale; }
@Override
public float getWidth(float extra) { return baseWidth * scale + extra * baseScale; }
@Override
public float getHeight() { return baseHeight * scale; }
@Override
public float getHeight(float extra) { return baseHeight * scale + extra * baseScale; }
@Override
public float getMinX() { return minX; }
@Override
public float getMinX(float extra) { return minX + extra * scale; }
@Override
public float getMinY() { return minY; }
@Override
public float getMinY(float extra) { return minY + extra * scale; }
@Override
public float getMaxX() { return maxX; }
@Override
public float getMaxX(float extra) { return maxX + extra * scale; }
@Override
public float getMaxY() { return maxY; }
@Override
public float getMaxY(float extra) { return maxY + extra * scale; }
@Override
public float getCenterX() { return minX + (maxX - minX) * 0.5F; }
@Override
public float getCenterX(float extra) { return minX + (maxX - minX) * 0.5F + extra * scale; }
@Override
public float getCenterY() { return minY + (maxY - minY) * 0.5F; }
@Override
public float getCenterY(float extra) { return minY + (maxY - minY) * 0.5F + extra * scale; }
@Override
public IGuiBox setX(float x) {
baseX = x;
return this;
}
@Override
public IGuiBox setY(float y) {
baseY = y;
return this;
}
@Override
public IGuiBox setWidth(float width) {
baseWidth = width;
this.width = baseWidth * baseScale;
return this;
}
@Override
public IGuiBox setHeight(float height) {
baseHeight = height;
this.height = baseHeight * baseScale;
return this;
}
@Override
public IGuiBox setScale(float scale) {
baseScale = scale;
width = baseWidth * baseScale;
height = baseHeight * baseScale;
return this;
}
@Override
public IGuiBox move(float xOffset, float yOffset) { return setXY(baseX + xOffset, baseY + yOffset); }
@Override
public IGuiBox resize(float xGrowth, float yGrowth) { return setBounds(baseWidth + xGrowth, baseHeight + yGrowth); }
@Override
public IGuiBox scale(float scale) { return setScale(scale * baseScale); }
@Override
public float getBaseScale() { return baseScale; }
@Override
public float getBaseWidth() { return baseWidth; }
@Override
public float getBaseHeight() { return baseHeight; }
@Override
public String toString() { return "GuiBox[minX="+minX+", minY="+minY+", maxX="+maxX+", maxY="+maxY+", width="+width+", height="+height+"]"; }
}
package speiger.src.coreengine.rendering.guiOld.helper.box;
import java.util.List;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList;
public class GuiBox implements IGuiBox
{
ObjectList<IGuiBox> children = new ObjectArrayList<>();
IGuiBox parent;
float minX;
float minY;
float maxX;
float maxY;
float width;
float height;
float scale = 1F;
float baseX;
float baseY;
float baseWidth;
float baseHeight;
float baseScale = 1F;
protected GuiBox() {}
public GuiBox(float x, float y, float width, float height) {
set(x, y, width, height);
onChanged();
}
public static IGuiBox clone(IGuiBox box) {
return new GuiBox(box.getMinX(), box.getMinY(), box.getWidth(), box.getHeight());
}
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);
}
@Override
public IGuiBox addChild(IGuiBox box) {
children.add(box);
box.setParent(this);
return this;
}
@Override
public IGuiBox removeChild(IGuiBox box) {
if(children.remove(box)) box.setParent(null);
return this;
}
@Override
public IGuiBox clearChildren() {
for(int i = 0,m=children.size();i<m;i++) {
children.get(i).setParent(null);
}
children.clear();
return this;
}
@Override
public List<IGuiBox> children() {
return children.unmodifiable();
}
@Override
public IGuiBox onChanged() {
minX = parent == null ? baseX : parent.getMinX(baseX);
minY = parent == null ? baseY : parent.getMinY(baseY);
maxX = parent == null ? baseX + width : parent.getMinX(baseX + width);
maxY = parent == null ? baseY + height : parent.getMinY(baseY + height);
scale = parent == null ? baseScale : parent.getScale() * baseScale;
for(int i = 0,m=children.size();i<m;i++) {
children.get(i).onChanged();
}
return this;
}
@Override
public IGuiBox setParent(IGuiBox box) {
parent = box;
return this;
}
@Override
public IGuiBox getParent() { return parent; }
@Override
public float getScale() { return scale; }
@Override
public float getBaseX() { return baseX; }
@Override
public float getBaseY() { return baseY; }
@Override
public float getRelativeX() { return parent != null ? baseX : 0F; }
@Override
public float getRelativeY() { return parent != null ? baseY : 0F; }
@Override
public float getWidth() { return baseWidth * scale; }
@Override
public float getWidth(float extra) { return baseWidth * scale + extra * baseScale; }
@Override
public float getHeight() { return baseHeight * scale; }
@Override
public float getHeight(float extra) { return baseHeight * scale + extra * baseScale; }
@Override
public float getMinX() { return minX; }
@Override
public float getMinX(float extra) { return minX + extra * scale; }
@Override
public float getMinY() { return minY; }
@Override
public float getMinY(float extra) { return minY + extra * scale; }
@Override
public float getMaxX() { return maxX; }
@Override
public float getMaxX(float extra) { return maxX + extra * scale; }
@Override
public float getMaxY() { return maxY; }
@Override
public float getMaxY(float extra) { return maxY + extra * scale; }
@Override
public float getCenterX() { return minX + (maxX - minX) * 0.5F; }
@Override
public float getCenterX(float extra) { return minX + (maxX - minX) * 0.5F + extra * scale; }
@Override
public float getCenterY() { return minY + (maxY - minY) * 0.5F; }
@Override
public float getCenterY(float extra) { return minY + (maxY - minY) * 0.5F + extra * scale; }
@Override
public IGuiBox setX(float x) {
baseX = x;
return this;
}
@Override
public IGuiBox setY(float y) {
baseY = y;
return this;
}
@Override
public IGuiBox setWidth(float width) {
baseWidth = width;
this.width = baseWidth * baseScale;
return this;
}
@Override
public IGuiBox setHeight(float height) {
baseHeight = height;
this.height = baseHeight * baseScale;
return this;
}
@Override
public IGuiBox setScale(float scale) {
baseScale = scale;
width = baseWidth * baseScale;
height = baseHeight * baseScale;
return this;
}
@Override
public IGuiBox move(float xOffset, float yOffset) { return setXY(baseX + xOffset, baseY + yOffset); }
@Override
public IGuiBox resize(float xGrowth, float yGrowth) { return setBounds(baseWidth + xGrowth, baseHeight + yGrowth); }
@Override
public IGuiBox scale(float scale) { return setScale(scale * baseScale); }
@Override
public float getBaseScale() { return baseScale; }
@Override
public float getBaseWidth() { return baseWidth; }
@Override
public float getBaseHeight() { return baseHeight; }
@Override
public String toString() { return "GuiBox[minX="+minX+", minY="+minY+", maxX="+maxX+", maxY="+maxY+", width="+width+", height="+height+"]"; }
}