diff --git a/src/main/java/speiger/src/coreengine/math/vector/matrix/Matrix4f.java b/src/main/java/speiger/src/coreengine/math/vector/matrix/Matrix4f.java index d13fe55..92d78f2 100644 --- a/src/main/java/speiger/src/coreengine/math/vector/matrix/Matrix4f.java +++ b/src/main/java/speiger/src/coreengine/math/vector/matrix/Matrix4f.java @@ -538,36 +538,48 @@ public class Matrix4f { public Matrix4f scale(float value) { return scale(value, value, value); } public Matrix4f scale(float x, float y, float z) { - data[M00] *= x; - data[M01] *= x; - data[M02] *= x; - data[M03] *= x; - data[M10] *= y; - data[M11] *= y; - data[M12] *= y; - data[M13] *= y; - data[M20] *= z; - data[M21] *= z; - data[M22] *= z; - data[M23] *= z; + if(x != 1F) { + data[M00] *= x; + data[M01] *= x; + data[M02] *= x; + data[M03] *= x; + } + if(y != 1F) { + data[M10] *= y; + data[M11] *= y; + data[M12] *= y; + data[M13] *= y; + } + if(z != 1F) { + data[M20] *= z; + data[M21] *= z; + data[M22] *= z; + data[M23] *= z; + } return evaluateProps(); } public Matrix4f unscale(float scale) { return unscale(scale, scale, scale); } public Matrix4f unscale(float x, float y, float z) { - data[M00] /= x; - data[M01] /= x; - data[M02] /= x; - data[M03] /= x; - data[M10] /= y; - data[M11] /= y; - data[M12] /= y; - data[M13] /= y; - data[M20] /= z; - data[M21] /= z; - data[M22] /= z; - data[M23] /= z; + if(x != 1F) { + data[M00] /= x; + data[M01] /= x; + data[M02] /= x; + data[M03] /= x; + } + if(y != 1F) { + data[M10] /= y; + data[M11] /= y; + data[M12] /= y; + data[M13] /= y; + } + if(z != 1F) { + data[M20] /= z; + data[M21] /= z; + data[M22] /= z; + data[M23] /= z; + } return evaluateProps(); } diff --git a/src/main/java/speiger/src/coreengine/math/vector/matrix/Matrix4fStack.java b/src/main/java/speiger/src/coreengine/math/vector/matrix/Matrix4fStack.java index f992a78..2b4433f 100644 --- a/src/main/java/speiger/src/coreengine/math/vector/matrix/Matrix4fStack.java +++ b/src/main/java/speiger/src/coreengine/math/vector/matrix/Matrix4fStack.java @@ -6,15 +6,26 @@ import speiger.src.collections.utils.Stack; public class Matrix4fStack extends Matrix4f { Stack stack = new ObjectArrayList<>(); - public void push() { - stack.push(new Matrix4f(this)); + public Matrix4f push() { + Matrix4f matrix = new Matrix4f(this); + stack.push(matrix); + return matrix; } public void pop() { load(stack.pop()); } + public void popRoot() { + load(stack.peek(stack.size()-1)); + stack.clear(); + } + public int size() { return stack.size(); } + + public Matrix4f copyCurrent() { + return new Matrix4f(this); + } } diff --git a/src/main/java/speiger/src/coreengine/rendering/gui/renderer/IUIRenderer.java b/src/main/java/speiger/src/coreengine/rendering/gui/renderer/IUIRenderer.java index 7de4463..d2a1550 100644 --- a/src/main/java/speiger/src/coreengine/rendering/gui/renderer/IUIRenderer.java +++ b/src/main/java/speiger/src/coreengine/rendering/gui/renderer/IUIRenderer.java @@ -7,6 +7,7 @@ import speiger.src.coreengine.math.vector.matrix.Matrix4f; import speiger.src.coreengine.math.vector.quaternion.Quaternion; import speiger.src.coreengine.rendering.guiOld.helper.box.IGuiBox; import speiger.src.coreengine.rendering.models.DrawCall; +import speiger.src.coreengine.rendering.tesselation.format.VertexFormat; import speiger.src.coreengine.rendering.textures.base.ITexture; public interface IUIRenderer { @@ -31,7 +32,7 @@ public interface IUIRenderer { public void rotate(Quaternion rotation); public void drawCustom(Consumer matrix); - public void drawCustom(DrawCall drawcall); + public void drawCustom(VertexFormat format, DrawCall drawcall); public void drawLine(float minX, float minY, float maxX, float maxY, float zLevel, int color); diff --git a/src/main/java/speiger/src/coreengine/rendering/gui/renderer/SimpleUIRenderer.java b/src/main/java/speiger/src/coreengine/rendering/gui/renderer/SimpleUIRenderer.java index 97a8c8e..e9584fb 100644 --- a/src/main/java/speiger/src/coreengine/rendering/gui/renderer/SimpleUIRenderer.java +++ b/src/main/java/speiger/src/coreengine/rendering/gui/renderer/SimpleUIRenderer.java @@ -1,19 +1,36 @@ package speiger.src.coreengine.rendering.gui.renderer; +import java.util.List; import java.util.function.Consumer; import speiger.src.collections.objects.lists.ObjectArrayList; -import speiger.src.collections.utils.Stack; import speiger.src.coreengine.math.misc.Facing; +import speiger.src.coreengine.math.vector.floats.Vec4f; import speiger.src.coreengine.math.vector.matrix.Matrix4f; import speiger.src.coreengine.math.vector.matrix.Matrix4fStack; import speiger.src.coreengine.math.vector.quaternion.Quaternion; import speiger.src.coreengine.rendering.guiOld.helper.box.IGuiBox; import speiger.src.coreengine.rendering.models.DrawCall; +import speiger.src.coreengine.rendering.tesselation.buffer.VertexBuilder; +import speiger.src.coreengine.rendering.tesselation.format.VertexFormat; +import speiger.src.coreengine.rendering.tesselation.format.VertexTypes; +import speiger.src.coreengine.rendering.utils.values.GLMode; -public class SimpleUIRenderer implements IUIRenderer { +public class SimpleUIRenderer implements IUIRenderer, AutoCloseable { TexturedRect cachedRect = new TexturedRect(); - Matrix4fStack transformCache = new Matrix4fStack(); + Matrix4fStack transform = new Matrix4fStack(); + List transformCache = new ObjectArrayList<>(new Matrix4f()); + int currentMatrix = 0; + int lastTexture = 0; + List drawCalls = new ObjectArrayList<>(); + + VertexBuilder builder = new VertexBuilder(Short.MAX_VALUE); + + + @Override + public void close() throws Exception { + builder.close(); + } @Override public boolean isInScissors(IGuiBox box) { @@ -39,55 +56,156 @@ public class SimpleUIRenderer implements IUIRenderer { } @Override +<<<<<<< HEAD public void pushTransform() { transformCache.push(); } - @Override - public void popTransform() { transformCache.pop(); } - @Override - public void translate(float z) { transformCache.translateZ(z); } - @Override - public void translate(float x, float y) { transformCache.translate(x, y); } - @Override - public void translate(float x, float y, float z) { transformCache.translate(x, y, z); } - @Override - public void scale(float scale) { transformCache.scale(scale); } - @Override - public void scale(float x, float y) { transformCache.scale(x, y, 1F); } - @Override - public void rotate(Quaternion rotation) { transformCache.rotate(rotation); } +======= + public void pushTransform() { + transform.push(); + invalidateMatrix(); + } +>>>>>>> branch 'master' of ssh://git@git.speiger.com/Speiger/SimpleJavaEngine.git @Override - public void drawCustom(Consumer matrix) { - flush(); +<<<<<<< HEAD + public void popTransform() { transformCache.pop(); } +======= + public void popTransform() { + transform.pop(); + invalidateMatrix(); + } + +>>>>>>> branch 'master' of ssh://git@git.speiger.com/Speiger/SimpleJavaEngine.git + @Override +<<<<<<< HEAD + public void translate(float z) { transformCache.translateZ(z); } +======= + public void translate(float z) { + transform.translate(0, 0, z); + invalidateMatrix(); + } + +>>>>>>> branch 'master' of ssh://git@git.speiger.com/Speiger/SimpleJavaEngine.git + @Override +<<<<<<< HEAD + public void translate(float x, float y) { transformCache.translate(x, y); } +======= + public void translate(float x, float y) { + transform.translate(x, y); + invalidateMatrix(); + } + +>>>>>>> branch 'master' of ssh://git@git.speiger.com/Speiger/SimpleJavaEngine.git + @Override +<<<<<<< HEAD + public void translate(float x, float y, float z) { transformCache.translate(x, y, z); } +======= + public void translate(float x, float y, float z) { + transform.translate(x, y, z); + invalidateMatrix(); + } + +>>>>>>> branch 'master' of ssh://git@git.speiger.com/Speiger/SimpleJavaEngine.git + @Override +<<<<<<< HEAD + public void scale(float scale) { transformCache.scale(scale); } +======= + public void scale(float scale) { + transform.scale(scale); + invalidateMatrix(); + } + +>>>>>>> branch 'master' of ssh://git@git.speiger.com/Speiger/SimpleJavaEngine.git + @Override +<<<<<<< HEAD + public void scale(float x, float y) { transformCache.scale(x, y, 1F); } +======= + public void scale(float x, float y) { + transform.scale(x, y, 1F); + invalidateMatrix(); + } + +>>>>>>> branch 'master' of ssh://git@git.speiger.com/Speiger/SimpleJavaEngine.git + @Override +<<<<<<< HEAD + public void rotate(Quaternion rotation) { transformCache.rotate(rotation); } +======= + public void rotate(Quaternion rotation) { + transform.rotate(rotation); + invalidateMatrix(); + } + + protected void invalidateMatrix() { + pushDrawcall(); + currentMatrix = -1; + } + + protected void validateMatrix() { + if(currentMatrix != -1) return; + for(int i = transformCache.size();i>=0;i--) { + if(transformCache.get(i).equals(transform)) { + currentMatrix = i; + return; + } + } + currentMatrix = transformCache.size(); + transformCache.add(transform.copyCurrent()); + } + + protected void ensureDrawCall(GLMode mode, VertexFormat format, int texture) { + if(!builder.is(mode, format) || lastTexture != texture) { + pushDrawcall(); + lastTexture = texture; + builder.start(mode, format); + } + } + + private void pushDrawcall() { + if(builder.hasData()) { + int start = builder.size(); + drawCalls.add(new UIDrawCall(builder.getMode(), start, builder.last()-start, lastTexture, currentMatrix, Vec4f.ZERO, 0F)); + builder.endDrawCall(false); + } } @Override - public void drawCustom(DrawCall drawcall) { - + public void drawCustom(Consumer matrix) { + validateMatrix(); + } + + @Override + public void drawCustom(VertexFormat format, DrawCall drawcall) { + validateMatrix(); + ensureDrawCall(drawcall.glType(), format, drawcall.textureId()); + builder.putBulk(drawcall.data()); } @Override public void drawLine(float minX, float minY, float maxX, float maxY, float zLevel, int color) { - + validateMatrix(); + ensureDrawCall(GLMode.TRIANGLES, VertexTypes.POS_RGBA, 0); } @Override public void drawFrame(float minX, float minY, float maxX, float maxY, float zLevel, int color) { - + validateMatrix(); + ensureDrawCall(GLMode.QUADS, VertexTypes.POS_RGBA, 0); } @Override public void drawRect(float minX, float minY, float maxX, float maxY, float zLevel, int color) { - + validateMatrix(); + ensureDrawCall(GLMode.QUADS, VertexTypes.POS_RGBA, 0); } @Override public void drawGradientRect(float minX, float minY, float maxX, float maxY, float zLevel, int startColor, int endColor, Facing facing) { - + validateMatrix(); + ensureDrawCall(GLMode.QUADS, VertexTypes.POS_RGBA, 0); } @Override public void drawTexturedRect(float minX, float minY, float maxX, float maxY, float zLevel, int texture, float minU, float minV, float maxU, float maxV, int color) { - + validateMatrix(); + ensureDrawCall(GLMode.QUADS, VertexTypes.POS_TEX_RGBA, texture); } - -} +} \ No newline at end of file diff --git a/src/main/java/speiger/src/coreengine/rendering/gui/renderer/UIDrawCall.java b/src/main/java/speiger/src/coreengine/rendering/gui/renderer/UIDrawCall.java new file mode 100644 index 0000000..6bcea8b --- /dev/null +++ b/src/main/java/speiger/src/coreengine/rendering/gui/renderer/UIDrawCall.java @@ -0,0 +1,8 @@ +package speiger.src.coreengine.rendering.gui.renderer; + +import speiger.src.coreengine.math.vector.floats.Vec4f; +import speiger.src.coreengine.rendering.utils.values.GLMode; + +public record UIDrawCall(GLMode mode, int start, int length, int texture, int matrix, Vec4f frame, float roundness) { + +} diff --git a/src/main/java/speiger/src/coreengine/rendering/guiOld/renderer/UIRenderer.java b/src/main/java/speiger/src/coreengine/rendering/guiOld/renderer/UIRenderer.java index 95adf12..09572a2 100644 --- a/src/main/java/speiger/src/coreengine/rendering/guiOld/renderer/UIRenderer.java +++ b/src/main/java/speiger/src/coreengine/rendering/guiOld/renderer/UIRenderer.java @@ -396,7 +396,7 @@ public class UIRenderer implements IReloadableResource applyAlignment(0, 0, width, height, 0, alignHelper); for(DrawCall call : drawCalls) { - ensureDrawing(call.glType(), call.textureId() > 0); + ensureDrawing(call.glType().glValue(), call.textureId() > 0); FloatBuffer buffer = ByteBuffer.wrap(call.data()).order(ByteOrder.nativeOrder()).asFloatBuffer(); for(int i = 0,m=buffer.remaining();i+9<=m;i+=9) { diff --git a/src/main/java/speiger/src/coreengine/rendering/models/DrawCall.java b/src/main/java/speiger/src/coreengine/rendering/models/DrawCall.java index e8670a7..121b619 100644 --- a/src/main/java/speiger/src/coreengine/rendering/models/DrawCall.java +++ b/src/main/java/speiger/src/coreengine/rendering/models/DrawCall.java @@ -4,10 +4,12 @@ import java.nio.ByteBuffer; import java.nio.ByteOrder; import java.util.List; -public record DrawCall(int glType, int textureId, byte[] data, int size) { +import speiger.src.coreengine.rendering.utils.values.GLMode; + +public record DrawCall(GLMode glType, int textureId, byte[] data, int size) { @Deprecated(forRemoval = true) - public DrawCall(int glType, int textureId, float[] data, int size) { + public DrawCall(GLMode glType, int textureId, float[] data, int size) { this(glType, textureId, convert(data), size); } diff --git a/src/main/java/speiger/src/coreengine/rendering/tesselation/buffer/IVertexBuilder.java b/src/main/java/speiger/src/coreengine/rendering/tesselation/buffer/IVertexBuilder.java index 01e4d60..fe63366 100644 --- a/src/main/java/speiger/src/coreengine/rendering/tesselation/buffer/IVertexBuilder.java +++ b/src/main/java/speiger/src/coreengine/rendering/tesselation/buffer/IVertexBuilder.java @@ -9,7 +9,7 @@ import speiger.src.coreengine.rendering.utils.values.GLMode; public interface IVertexBuilder extends IVertexBuffer { public VertexElement current(); public IVertexBuilder nextElement(); - public IVertexBuilder endDrawCall(); + public IVertexBuilder endDrawCall(boolean store); public List getDrawCalls(); public IVertexBuilder put(int offset, byte value); diff --git a/src/main/java/speiger/src/coreengine/rendering/tesselation/buffer/VertexBuilder.java b/src/main/java/speiger/src/coreengine/rendering/tesselation/buffer/VertexBuilder.java index 151678d..b2e8a98 100644 --- a/src/main/java/speiger/src/coreengine/rendering/tesselation/buffer/VertexBuilder.java +++ b/src/main/java/speiger/src/coreengine/rendering/tesselation/buffer/VertexBuilder.java @@ -11,7 +11,7 @@ import speiger.src.coreengine.rendering.tesselation.format.VertexElement; import speiger.src.coreengine.rendering.tesselation.format.VertexFormat; import speiger.src.coreengine.rendering.utils.values.GLMode; -public class VertexBuilder implements IVertexBuilder { +public class VertexBuilder implements IVertexBuilder, AutoCloseable { GLMode mode; ByteBuffer buffer; VertexFormat format; @@ -42,11 +42,22 @@ public class VertexBuilder implements IVertexBuilder { return this; } + public boolean is(GLMode mode, VertexFormat format) { return this.mode == mode && this.format == format; } + public GLMode getMode() { return mode; } + public VertexFormat getFormat() { return format; } + private void ensureCapacity(int newValue) { - if(buffer.isDirect() && totalStoredBytes + newValue >= buffer.capacity()) { + if(totalStoredBytes + newValue >= buffer.capacity()) { int oldSize = buffer.capacity(); int newSize = Math.max(oldSize + (oldSize >> 1), oldSize + newValue); - buffer = MemoryUtil.memRealloc(buffer, newSize); //TODO that if the old buffer gets deallocated + if(buffer.isDirect()) { + buffer = MemoryUtil.memRealloc(buffer, newSize); + } + else { + ByteBuffer newBuffer = ByteBuffer.allocate(newSize); + newBuffer.put(buffer).position(0); + buffer = newBuffer; + } } } @@ -75,9 +86,11 @@ public class VertexBuilder implements IVertexBuilder { return this; } - public VertexBuilder endDrawCall() { - if(drawCalls == null) drawCalls = new ObjectArrayList<>(); - drawCalls.add(new BufferDrawCall(mode, lastVertecies, vertecies)); + public VertexBuilder endDrawCall(boolean store) { + if(store) { + if(drawCalls == null) drawCalls = new ObjectArrayList<>(); + drawCalls.add(new BufferDrawCall(mode, lastVertecies, vertecies)); + } lastVertecies = vertecies; return this; } @@ -103,6 +116,8 @@ public class VertexBuilder implements IVertexBuilder { @Override public int size() { return vertecies; } + public int last() { return lastVertecies; } + public boolean hasData() { return vertecies > lastVertecies; } @Override public IVertexBuilder put(int offset, byte value) { @@ -132,6 +147,14 @@ public class VertexBuilder implements IVertexBuilder { return this; } + public VertexBuilder putBulk(byte[] source) { + ensureCapacity(source.length + format.totalOffset()); + buffer.position(totalStoredBytes).put(source).position(0); + vertecies += source.length / format.totalOffset(); + totalStoredBytes += source.length; + return this; + } + public VertexBuilder putBulk(ByteBuffer source) { ensureCapacity(source.limit() + format.totalOffset()); buffer.position(totalStoredBytes).put(source).position(0); @@ -141,7 +164,7 @@ public class VertexBuilder implements IVertexBuilder { } public VertexBuilder copy(ByteBuffer buffer) { - buffer.put(buffer.position(), this.buffer, 0, this.buffer.position()); + buffer.put(buffer.position(), this.buffer, 0, totalStoredBytes); return this; } diff --git a/src/main/java/speiger/src/coreengine/rendering/tesselation/format/VertexTypes.java b/src/main/java/speiger/src/coreengine/rendering/tesselation/format/VertexTypes.java index d505d41..3c209de 100644 --- a/src/main/java/speiger/src/coreengine/rendering/tesselation/format/VertexTypes.java +++ b/src/main/java/speiger/src/coreengine/rendering/tesselation/format/VertexTypes.java @@ -10,7 +10,8 @@ public class VertexTypes { public static final VertexElement RGBA = new VertexElement(4, Usage.COLOR); public static final VertexElement NORMAL = new VertexElement(3, Usage.NORMAL); - public static final VertexFormat POS_RGB_3D = VertexFormat.builder().add(POSITION_3D).add(RGB).build(); - public static final VertexFormat POS_RGBA_3D = VertexFormat.builder().add(POSITION_3D).add(RGBA).build(); + public static final VertexFormat POS_RGB = VertexFormat.builder().add(POSITION_3D).add(RGB).build(); + public static final VertexFormat POS_RGBA = VertexFormat.builder().add(POSITION_3D).add(RGBA).build(); + public static final VertexFormat POS_TEX_RGBA = VertexFormat.builder().add(POSITION_3D).add(TEXTURE).add(RGBA).build(); public static final VertexFormat TESTING = VertexFormat.builder().add(POSITION_3D).add(TEXTURE).add(RGBA).build(); } diff --git a/src/main/java/speiger/src/coreengine/rendering/tesselationOld/Tesselator.java b/src/main/java/speiger/src/coreengine/rendering/tesselationOld/Tesselator.java index 047ddfc..71c6cc2 100644 --- a/src/main/java/speiger/src/coreengine/rendering/tesselationOld/Tesselator.java +++ b/src/main/java/speiger/src/coreengine/rendering/tesselationOld/Tesselator.java @@ -8,6 +8,7 @@ import speiger.src.coreengine.rendering.models.DrawCall; import speiger.src.coreengine.rendering.tesselation.format.VertexElement; import speiger.src.coreengine.rendering.tesselation.format.VertexFormat; import speiger.src.coreengine.rendering.tesselation.format.VertexElement.Usage; +import speiger.src.coreengine.rendering.utils.values.GLMode; public class Tesselator implements IVertexBuilder { @@ -202,7 +203,7 @@ public class Tesselator implements IVertexBuilder public DrawCall getDrawCall(int texture) { float[] data = new float[currentList.totalOffset() * vertexes]; buffer.get(data); - return new DrawCall(drawType, texture, data, vertexes); + return new DrawCall(GLMode.byId(drawType), texture, data, vertexes); } public boolean isDrawing() { return drawing; } diff --git a/src/main/java/speiger/src/coreengine/rendering/utils/values/GLMode.java b/src/main/java/speiger/src/coreengine/rendering/utils/values/GLMode.java index 4494046..da63dfd 100644 --- a/src/main/java/speiger/src/coreengine/rendering/utils/values/GLMode.java +++ b/src/main/java/speiger/src/coreengine/rendering/utils/values/GLMode.java @@ -29,6 +29,13 @@ public enum GLMode implements IGLMode { GL11.glDrawElements(glMode, length, glMode, length); } + public static GLMode byId(int id) { + for(GLMode value : GLMode.values()) { + if(value.glValue() == id) return value; + } + throw new ArrayIndexOutOfBoundsException("GL["+id+"] isn't a valid GL Draw Mode"); + } + @Override public int glValue() { return glMode; } @Override