This commit is contained in:
Speiger 2025-04-21 23:01:32 +02:00
commit 5a82dfcf2d
12 changed files with 253 additions and 69 deletions

View File

@ -538,36 +538,48 @@ public class Matrix4f {
public Matrix4f scale(float value) { return scale(value, value, value); } public Matrix4f scale(float value) { return scale(value, value, value); }
public Matrix4f scale(float x, float y, float z) { public Matrix4f scale(float x, float y, float z) {
if(x != 1F) {
data[M00] *= x; data[M00] *= x;
data[M01] *= x; data[M01] *= x;
data[M02] *= x; data[M02] *= x;
data[M03] *= x; data[M03] *= x;
}
if(y != 1F) {
data[M10] *= y; data[M10] *= y;
data[M11] *= y; data[M11] *= y;
data[M12] *= y; data[M12] *= y;
data[M13] *= y; data[M13] *= y;
}
if(z != 1F) {
data[M20] *= z; data[M20] *= z;
data[M21] *= z; data[M21] *= z;
data[M22] *= z; data[M22] *= z;
data[M23] *= z; data[M23] *= z;
}
return evaluateProps(); return evaluateProps();
} }
public Matrix4f unscale(float scale) { return unscale(scale, scale, scale); } public Matrix4f unscale(float scale) { return unscale(scale, scale, scale); }
public Matrix4f unscale(float x, float y, float z) { public Matrix4f unscale(float x, float y, float z) {
if(x != 1F) {
data[M00] /= x; data[M00] /= x;
data[M01] /= x; data[M01] /= x;
data[M02] /= x; data[M02] /= x;
data[M03] /= x; data[M03] /= x;
}
if(y != 1F) {
data[M10] /= y; data[M10] /= y;
data[M11] /= y; data[M11] /= y;
data[M12] /= y; data[M12] /= y;
data[M13] /= y; data[M13] /= y;
}
if(z != 1F) {
data[M20] /= z; data[M20] /= z;
data[M21] /= z; data[M21] /= z;
data[M22] /= z; data[M22] /= z;
data[M23] /= z; data[M23] /= z;
}
return evaluateProps(); return evaluateProps();
} }

View File

@ -6,15 +6,26 @@ import speiger.src.collections.utils.Stack;
public class Matrix4fStack extends Matrix4f { public class Matrix4fStack extends Matrix4f {
Stack<Matrix4f> stack = new ObjectArrayList<>(); Stack<Matrix4f> stack = new ObjectArrayList<>();
public void push() { public Matrix4f push() {
stack.push(new Matrix4f(this)); Matrix4f matrix = new Matrix4f(this);
stack.push(matrix);
return matrix;
} }
public void pop() { public void pop() {
load(stack.pop()); load(stack.pop());
} }
public void popRoot() {
load(stack.peek(stack.size()-1));
stack.clear();
}
public int size() { public int size() {
return stack.size(); return stack.size();
} }
public Matrix4f copyCurrent() {
return new Matrix4f(this);
}
} }

View File

@ -7,6 +7,7 @@ import speiger.src.coreengine.math.vector.matrix.Matrix4f;
import speiger.src.coreengine.math.vector.quaternion.Quaternion; import speiger.src.coreengine.math.vector.quaternion.Quaternion;
import speiger.src.coreengine.rendering.guiOld.helper.box.IGuiBox; import speiger.src.coreengine.rendering.guiOld.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.models.DrawCall; import speiger.src.coreengine.rendering.models.DrawCall;
import speiger.src.coreengine.rendering.tesselation.format.VertexFormat;
import speiger.src.coreengine.rendering.textures.base.ITexture; import speiger.src.coreengine.rendering.textures.base.ITexture;
public interface IUIRenderer { public interface IUIRenderer {
@ -31,7 +32,7 @@ public interface IUIRenderer {
public void rotate(Quaternion rotation); public void rotate(Quaternion rotation);
public void drawCustom(Consumer<Matrix4f> matrix); public void drawCustom(Consumer<Matrix4f> 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); public void drawLine(float minX, float minY, float maxX, float maxY, float zLevel, int color);

View File

@ -1,19 +1,36 @@
package speiger.src.coreengine.rendering.gui.renderer; package speiger.src.coreengine.rendering.gui.renderer;
import java.util.List;
import java.util.function.Consumer; import java.util.function.Consumer;
import speiger.src.collections.objects.lists.ObjectArrayList; 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.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.Matrix4f;
import speiger.src.coreengine.math.vector.matrix.Matrix4fStack; import speiger.src.coreengine.math.vector.matrix.Matrix4fStack;
import speiger.src.coreengine.math.vector.quaternion.Quaternion; import speiger.src.coreengine.math.vector.quaternion.Quaternion;
import speiger.src.coreengine.rendering.guiOld.helper.box.IGuiBox; import speiger.src.coreengine.rendering.guiOld.helper.box.IGuiBox;
import speiger.src.coreengine.rendering.models.DrawCall; 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(); TexturedRect cachedRect = new TexturedRect();
Matrix4fStack transformCache = new Matrix4fStack(); Matrix4fStack transform = new Matrix4fStack();
List<Matrix4f> transformCache = new ObjectArrayList<>(new Matrix4f());
int currentMatrix = 0;
int lastTexture = 0;
List<UIDrawCall> drawCalls = new ObjectArrayList<>();
VertexBuilder builder = new VertexBuilder(Short.MAX_VALUE);
@Override
public void close() throws Exception {
builder.close();
}
@Override @Override
public boolean isInScissors(IGuiBox box) { public boolean isInScissors(IGuiBox box) {
@ -39,55 +56,156 @@ public class SimpleUIRenderer implements IUIRenderer {
} }
@Override @Override
<<<<<<< HEAD
public void pushTransform() { transformCache.push(); } public void pushTransform() { transformCache.push(); }
@Override =======
public void popTransform() { transformCache.pop(); } public void pushTransform() {
@Override transform.push();
public void translate(float z) { transformCache.translateZ(z); } invalidateMatrix();
@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); }
>>>>>>> branch 'master' of ssh://git@git.speiger.com/Speiger/SimpleJavaEngine.git
@Override @Override
public void drawCustom(Consumer<Matrix4f> matrix) { <<<<<<< HEAD
flush(); 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 @Override
public void drawCustom(DrawCall drawcall) { public void drawCustom(Consumer<Matrix4f> matrix) {
validateMatrix();
}
@Override
public void drawCustom(VertexFormat format, DrawCall drawcall) {
validateMatrix();
ensureDrawCall(drawcall.glType(), format, drawcall.textureId());
builder.putBulk(drawcall.data());
} }
@Override @Override
public void drawLine(float minX, float minY, float maxX, float maxY, float zLevel, int color) { public void drawLine(float minX, float minY, float maxX, float maxY, float zLevel, int color) {
validateMatrix();
ensureDrawCall(GLMode.TRIANGLES, VertexTypes.POS_RGBA, 0);
} }
@Override @Override
public void drawFrame(float minX, float minY, float maxX, float maxY, float zLevel, int color) { public void drawFrame(float minX, float minY, float maxX, float maxY, float zLevel, int color) {
validateMatrix();
ensureDrawCall(GLMode.QUADS, VertexTypes.POS_RGBA, 0);
} }
@Override @Override
public void drawRect(float minX, float minY, float maxX, float maxY, float zLevel, int color) { public void drawRect(float minX, float minY, float maxX, float maxY, float zLevel, int color) {
validateMatrix();
ensureDrawCall(GLMode.QUADS, VertexTypes.POS_RGBA, 0);
} }
@Override @Override
public void drawGradientRect(float minX, float minY, float maxX, float maxY, float zLevel, int startColor, int endColor, Facing facing) { 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 @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) { 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);
} }
} }

View File

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

View File

@ -396,7 +396,7 @@ public class UIRenderer implements IReloadableResource
applyAlignment(0, 0, width, height, 0, alignHelper); applyAlignment(0, 0, width, height, 0, alignHelper);
for(DrawCall call : drawCalls) 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(); FloatBuffer buffer = ByteBuffer.wrap(call.data()).order(ByteOrder.nativeOrder()).asFloatBuffer();
for(int i = 0,m=buffer.remaining();i+9<=m;i+=9) for(int i = 0,m=buffer.remaining();i+9<=m;i+=9)
{ {

View File

@ -4,10 +4,12 @@ import java.nio.ByteBuffer;
import java.nio.ByteOrder; import java.nio.ByteOrder;
import java.util.List; 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) @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); this(glType, textureId, convert(data), size);
} }

View File

@ -9,7 +9,7 @@ import speiger.src.coreengine.rendering.utils.values.GLMode;
public interface IVertexBuilder extends IVertexBuffer { public interface IVertexBuilder extends IVertexBuffer {
public VertexElement current(); public VertexElement current();
public IVertexBuilder nextElement(); public IVertexBuilder nextElement();
public IVertexBuilder endDrawCall(); public IVertexBuilder endDrawCall(boolean store);
public List<BufferDrawCall> getDrawCalls(); public List<BufferDrawCall> getDrawCalls();
public IVertexBuilder put(int offset, byte value); public IVertexBuilder put(int offset, byte value);

View File

@ -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.tesselation.format.VertexFormat;
import speiger.src.coreengine.rendering.utils.values.GLMode; import speiger.src.coreengine.rendering.utils.values.GLMode;
public class VertexBuilder implements IVertexBuilder { public class VertexBuilder implements IVertexBuilder, AutoCloseable {
GLMode mode; GLMode mode;
ByteBuffer buffer; ByteBuffer buffer;
VertexFormat format; VertexFormat format;
@ -42,11 +42,22 @@ public class VertexBuilder implements IVertexBuilder {
return this; 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) { private void ensureCapacity(int newValue) {
if(buffer.isDirect() && totalStoredBytes + newValue >= buffer.capacity()) { if(totalStoredBytes + newValue >= buffer.capacity()) {
int oldSize = buffer.capacity(); int oldSize = buffer.capacity();
int newSize = Math.max(oldSize + (oldSize >> 1), oldSize + newValue); 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; return this;
} }
public VertexBuilder endDrawCall() { public VertexBuilder endDrawCall(boolean store) {
if(store) {
if(drawCalls == null) drawCalls = new ObjectArrayList<>(); if(drawCalls == null) drawCalls = new ObjectArrayList<>();
drawCalls.add(new BufferDrawCall(mode, lastVertecies, vertecies)); drawCalls.add(new BufferDrawCall(mode, lastVertecies, vertecies));
}
lastVertecies = vertecies; lastVertecies = vertecies;
return this; return this;
} }
@ -103,6 +116,8 @@ public class VertexBuilder implements IVertexBuilder {
@Override @Override
public int size() { return vertecies; } public int size() { return vertecies; }
public int last() { return lastVertecies; }
public boolean hasData() { return vertecies > lastVertecies; }
@Override @Override
public IVertexBuilder put(int offset, byte value) { public IVertexBuilder put(int offset, byte value) {
@ -132,6 +147,14 @@ public class VertexBuilder implements IVertexBuilder {
return this; 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) { public VertexBuilder putBulk(ByteBuffer source) {
ensureCapacity(source.limit() + format.totalOffset()); ensureCapacity(source.limit() + format.totalOffset());
buffer.position(totalStoredBytes).put(source).position(0); buffer.position(totalStoredBytes).put(source).position(0);
@ -141,7 +164,7 @@ public class VertexBuilder implements IVertexBuilder {
} }
public VertexBuilder copy(ByteBuffer buffer) { 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; return this;
} }

View File

@ -10,7 +10,8 @@ public class VertexTypes {
public static final VertexElement RGBA = new VertexElement(4, Usage.COLOR); public static final VertexElement RGBA = new VertexElement(4, Usage.COLOR);
public static final VertexElement NORMAL = new VertexElement(3, Usage.NORMAL); 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_RGB = 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_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(); public static final VertexFormat TESTING = VertexFormat.builder().add(POSITION_3D).add(TEXTURE).add(RGBA).build();
} }

View File

@ -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.VertexElement;
import speiger.src.coreengine.rendering.tesselation.format.VertexFormat; import speiger.src.coreengine.rendering.tesselation.format.VertexFormat;
import speiger.src.coreengine.rendering.tesselation.format.VertexElement.Usage; import speiger.src.coreengine.rendering.tesselation.format.VertexElement.Usage;
import speiger.src.coreengine.rendering.utils.values.GLMode;
public class Tesselator implements IVertexBuilder public class Tesselator implements IVertexBuilder
{ {
@ -202,7 +203,7 @@ public class Tesselator implements IVertexBuilder
public DrawCall getDrawCall(int texture) { public DrawCall getDrawCall(int texture) {
float[] data = new float[currentList.totalOffset() * vertexes]; float[] data = new float[currentList.totalOffset() * vertexes];
buffer.get(data); buffer.get(data);
return new DrawCall(drawType, texture, data, vertexes); return new DrawCall(GLMode.byId(drawType), texture, data, vertexes);
} }
public boolean isDrawing() { return drawing; } public boolean isDrawing() { return drawing; }

View File

@ -29,6 +29,13 @@ public enum GLMode implements IGLMode {
GL11.glDrawElements(glMode, length, glMode, length); 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 @Override
public int glValue() { return glMode; } public int glValue() { return glMode; }
@Override @Override