Progress on UI Renderer

This commit is contained in:
2026-08-16 21:22:28 +02:00
parent 3b074a2684
commit 56eae46176
28 changed files with 1329 additions and 1070 deletions
@@ -2,11 +2,11 @@ package speiger.src.coreengine.platform.graphics.api.core;
import speiger.src.coreengine.platform.graphics.api.buffer.VertexBuffer;
import speiger.src.coreengine.platform.graphics.api.mesh.Mesh;
import speiger.src.coreengine.platform.graphics.api.sampler.Sampler;
import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline;
import speiger.src.coreengine.platform.graphics.api.texture.Texture;
import speiger.src.coreengine.platform.graphics.api.utils.AccessType;
import speiger.src.coreengine.platform.graphics.api.utils.GraphicsResource;
import speiger.src.coreengine.platform.graphics.api.utils.SampledTexture;
public interface GraphicsCommandBuffer extends GraphicsResource, CommandBuffer {
GraphicsCommandBuffer begin();
@@ -14,7 +14,7 @@ public interface GraphicsCommandBuffer extends GraphicsResource, CommandBuffer {
GraphicsCommandBuffer pipeline(ShaderPipeline pipeline);
GraphicsCommandBuffer mesh(Mesh mesh);
GraphicsCommandBuffer texture(int binding, Texture texture, Sampler sampler);
GraphicsCommandBuffer texture(int binding, SampledTexture texture);
GraphicsCommandBuffer texture(int binding, Texture texture, AccessType access);
GraphicsCommandBuffer uniform(int binding, VertexBuffer buffer);
@@ -0,0 +1,13 @@
package speiger.src.coreengine.platform.graphics.api.utils;
import java.util.Objects;
import speiger.src.coreengine.platform.graphics.api.sampler.Sampler;
import speiger.src.coreengine.platform.graphics.api.texture.Texture;
public record SampledTexture(Texture texture, Sampler sampler) {
public SampledTexture {
Objects.requireNonNull(texture);
Objects.requireNonNull(sampler);
}
}
@@ -1,7 +1,5 @@
package speiger.src.coreengine.platform.graphics.api.vertex.builder;
import java.util.List;
import speiger.src.coreengine.math.vector.matrix.Matrix4f;
import speiger.src.coreengine.platform.graphics.api.shader.states.DrawMode;
import speiger.src.coreengine.platform.graphics.api.shader.states.GraphicsDataType;
@@ -11,8 +9,7 @@ import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout.Usage;
public interface IVertexBuffer extends IVertexBuilder {
Element current();
IVertexBuffer next();
IVertexBuffer finish();
List<BufferResult> results();
BufferResult finish();
default IVertexBuffer validate(Usage usage, GraphicsDataType type, int size) { return validate(this, usage, type, size); }
@@ -1,13 +1,9 @@
package speiger.src.coreengine.platform.graphics.api.vertex.builder;
import java.nio.ByteBuffer;
import java.util.List;
import org.lwjgl.system.MemoryUtil;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.collections.objects.lists.ObjectList;
import speiger.src.collections.objects.utils.ObjectLists;
import speiger.src.coreengine.platform.graphics.api.shader.states.DrawMode;
import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout;
import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout.Element;
@@ -24,7 +20,6 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable {
int vertexBytes;
int elementBytes;
int lastVertecies = 0;
ObjectList<BufferResult> results;
public VertexBuilder(int size) {
this(MemoryUtil.memAlloc(size));
@@ -40,6 +35,7 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable {
}
public VertexBuilder start(DrawMode mode, VertexLayout layout) {
if(index != 0) throw new IllegalStateException("Can't change Layout mid Writing");
this.mode = mode;
this.layout = layout;
return this;
@@ -52,10 +48,10 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable {
totalStoredBytes = 0;
vertexBytes = 0;
lastVertecies = 0;
results = null;
return this;
}
public boolean hasVertecies() { return lastVertecies < vertecies; }
public boolean is(DrawMode mode, VertexLayout layout) { return this.mode == mode && this.layout == layout; }
public DrawMode mode() { return mode; }
public VertexLayout getFormat() { return layout; }
@@ -73,16 +69,10 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable {
}
@Override
public IVertexBuffer finish() {
if(results == null) results = new ObjectArrayList<>();
results.add(new BufferResult(mode, lastVertecies, vertecies));
public BufferResult finish() {
BufferResult result = new BufferResult(mode, lastVertecies, vertecies);
lastVertecies = vertecies;
return this;
}
@Override
public List<BufferResult> results() {
return results == null ? ObjectLists.empty() : results.unmodifiable();
return result;
}
@Override
@@ -93,12 +83,8 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable {
elementBytes = 0;
if(index == 0) {
vertecies++;
if(mode == DrawMode.LINES || mode == DrawMode.LINE_STRIP) {
buffer.put(totalStoredBytes, buffer, totalStoredBytes - vertexBytes, vertexBytes);
vertecies++;
}
vertexBytes = 0;
ensureCapacity(totalStoredBytes + layout.bytes());
ensureCapacity(totalStoredBytes + (layout.bytes() * mode.primitiveLength()));
}
return this;
}
@@ -136,8 +122,6 @@ public class VertexBuilder implements IVertexBuffer, AutoCloseable {
return vertecies;
}
public VertexBuilder putBulk(byte[] source) {
if(index != 0) throw new IllegalStateException("Can't do bulk iterations when mid Building");
ensureCapacity(source.length + layout.bytes());
@@ -12,13 +12,13 @@ import speiger.src.coreengine.platform.graphics.api.buffer.VertexBuffer;
import speiger.src.coreengine.platform.graphics.api.buffer.states.BufferType;
import speiger.src.coreengine.platform.graphics.api.core.GraphicsCommandBuffer;
import speiger.src.coreengine.platform.graphics.api.mesh.Mesh;
import speiger.src.coreengine.platform.graphics.api.sampler.Sampler;
import speiger.src.coreengine.platform.graphics.api.shader.ColorTarget;
import speiger.src.coreengine.platform.graphics.api.shader.DepthTarget;
import speiger.src.coreengine.platform.graphics.api.shader.RasterizerState;
import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline;
import speiger.src.coreengine.platform.graphics.api.texture.Texture;
import speiger.src.coreengine.platform.graphics.api.utils.AccessType;
import speiger.src.coreengine.platform.graphics.api.utils.SampledTexture;
import speiger.src.coreengine.platform.graphics.api.utils.ScissorsManager;
import speiger.src.coreengine.platform.graphics.opengl.buffer.GLVertexBuffer;
import speiger.src.coreengine.platform.graphics.opengl.mesh.GLMesh;
@@ -118,15 +118,14 @@ public class GLImmidateCommandBuffer implements GraphicsCommandBuffer {
}
@Override
public GraphicsCommandBuffer texture(int binding, Texture texture, Sampler sampler) {
public GraphicsCommandBuffer texture(int binding, SampledTexture texture) {
Objects.requireNonNull(texture);
Objects.requireNonNull(sampler);
ensureDrawing();
Objects.requireNonNull(shader, "No Pipeline found");
Objects.requireNonNull(shader.samplers().byIndex(binding), "Texture["+binding+"] binding not found");
GLStates states = device.states;
states.textures.bind(binding, ((GLTexture)texture).id());
states.samplers.bind(binding, ((GLSampler)sampler).id());
states.textures.bind(binding, ((GLTexture)texture.texture()).id());
states.samplers.bind(binding, ((GLSampler)texture.sampler()).id());
recorded++;
return this;
}
@@ -16,7 +16,6 @@ import speiger.src.coreengine.platform.graphics.api.buffer.states.BufferType;
import speiger.src.coreengine.platform.graphics.api.buffer.states.IndeciesType;
import speiger.src.coreengine.platform.graphics.api.core.GraphicsCommandBuffer;
import speiger.src.coreengine.platform.graphics.api.mesh.Mesh;
import speiger.src.coreengine.platform.graphics.api.sampler.Sampler;
import speiger.src.coreengine.platform.graphics.api.shader.ColorTarget;
import speiger.src.coreengine.platform.graphics.api.shader.DepthTarget;
import speiger.src.coreengine.platform.graphics.api.shader.RasterizerState;
@@ -24,6 +23,7 @@ import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline;
import speiger.src.coreengine.platform.graphics.api.shader.states.DrawMode;
import speiger.src.coreengine.platform.graphics.api.texture.Texture;
import speiger.src.coreengine.platform.graphics.api.utils.AccessType;
import speiger.src.coreengine.platform.graphics.api.utils.SampledTexture;
import speiger.src.coreengine.platform.graphics.api.utils.ScissorsManager;
import speiger.src.coreengine.platform.graphics.api.utils.ScissorsManager.NoOp;
import speiger.src.coreengine.platform.graphics.opengl.buffer.GLVertexBuffer;
@@ -110,13 +110,12 @@ public class GLRecordingCommandBuffer implements GraphicsCommandBuffer {
}
@Override
public GraphicsCommandBuffer texture(int binding, Texture texture, Sampler sampler) {
public GraphicsCommandBuffer texture(int binding, SampledTexture texture) {
Objects.requireNonNull(texture);
Objects.requireNonNull(sampler);
ensureDrawing();
Objects.requireNonNull(shader, "No Pipeline found");
Objects.requireNonNull(shader.samplers().byIndex(binding), "Texture["+binding+"] binding not found");
tasks.add(new SetTexture(binding, (GLTexture)texture, (GLSampler)sampler, device.states));
tasks.add(new SetTexture(binding, (GLTexture)texture.texture(), (GLSampler)texture.sampler(), device.states));
return this;
}
@@ -94,14 +94,14 @@ public abstract non-sealed class GuiComponent extends FlagObject implements ICas
if(!comp.isVisible()) return false;
comp.updateAnimations(partialTicks);
if(comp.isScissored()) {
if(!renderer.isInScissors(comp.getBox())) return false;
renderer.pushScissors(comp.getBox());
if(!renderer.isClipping(comp.getBox())) return false;
renderer.pushClip(comp.getBox());
if(comp.renderer != null) {
comp.renderer.renderComponent(comp, renderer, mouseX, mouseY, partialTicks);
comp.renderChildren(renderer, mouseX, mouseY, partialTicks);
}
else comp.renderComponent(renderer, mouseX, mouseY, partialTicks);
renderer.popScissors();
renderer.popClip();
}
else if(comp.renderer != null) {
comp.renderer.renderComponent(comp, renderer, mouseX, mouseY, partialTicks);
@@ -16,6 +16,8 @@ public interface IGuiBox extends IScreenBox
public IGuiBox onChanged();
public static IGuiBox of(float x, float y, float width, float height) { return new GuiBox(x, y, width, height); }
public static IGuiBox parent(float padding) { return new ParentBox(padding); }
public static IGuiBox parent(float left, float top, float right, float bottom) { return new ParentBox(left, top, right, bottom); }
public default IGuiBox copy() { return GuiBox.clone(this); }
public default IGuiBox copy(float padding) { return GuiBox.clonePadded(this, padding); }
@@ -22,7 +22,7 @@ public class ParentBox implements IGuiBox
maxY = -value;
}
public ParentBox(float paddingTop, float paddingLeft, float paddingBottom, float paddingRight) {
public ParentBox(float paddingLeft, float paddingTop, float paddingRight, float paddingBottom) {
minX = paddingLeft;
minY = paddingTop;
maxX = paddingRight;
@@ -1,24 +1,38 @@
package speiger.src.coreengine.ui.gui.renderer;
import speiger.src.coreengine.math.vector.quaternion.Quaternion;
import speiger.src.coreengine.platform.graphics.api.utils.SampledTexture;
import speiger.src.coreengine.ui.gui.layout.box.IGuiBox;
import speiger.src.coreengine.ui.gui.utils.Align;
public interface IUIRenderer {
public boolean isInScissors(IGuiBox box);
public void pushScissors(IGuiBox box);
public void popScissors();
boolean isClipping(IGuiBox box);
void pushClip(IGuiBox box);
void popClip();
public void flush();
void pushTransform();
void popTransform();
public void pushTransform();
public void popTransform();
void translate(float z);
void translate(float x, float y);
public void translate(float z);
public void translate(float x, float y);
public void translate(float x, float y, float z);
void scale(float scale);
void scale(float x, float y);
public void scale(float scale);
public void scale(float x, float y);
void rotate(Quaternion rotation);
public void rotate(Quaternion rotation);
void align(Align vertical, Align horizontal);
void alignV(Align align);
void alignH(Align align);
void pushLayer(LayerType type);
void popLayer();
void drawLine(float startX, float startY, float endX, float endY, float lineWidth, int color);
void drawFrame(IGuiBox box, int color);
void drawRect(IGuiBox box, int color);
void drawImage(IGuiBox box, SampledTexture texture, int color);
void drawImage(IGuiBox box, SampledTexture texture, float minU, float minV, float maxU, float maxV, int color);
void drawCustom(UIDrawer drawer);
}
@@ -0,0 +1,7 @@
package speiger.src.coreengine.ui.gui.renderer;
public enum LayerType {
COMPONENT,
COMPONENT_STACK,
WINDOW;
}
@@ -0,0 +1,12 @@
package speiger.src.coreengine.ui.gui.renderer;
import speiger.src.coreengine.math.vector.matrix.Matrix4f;
import speiger.src.coreengine.platform.graphics.api.core.GraphicsCommandBuffer;
import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline;
import speiger.src.coreengine.platform.graphics.api.vertex.builder.IVertexBuilder;
public interface UIDrawer {
ShaderPipeline pipeline();
void buildVertecies(IVertexBuilder builder, Matrix4f matrix);
void setupExtra(GraphicsCommandBuffer buffer);
}
@@ -0,0 +1,215 @@
package speiger.src.coreengine.ui.gui.renderer;
import java.util.List;
import speiger.src.collections.objects.lists.ObjectArrayList;
import speiger.src.coreengine.math.vector.matrix.Matrix4fStack;
import speiger.src.coreengine.math.vector.quaternion.Quaternion;
import speiger.src.coreengine.platform.graphics.api.core.GraphicsDevice;
import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline;
import speiger.src.coreengine.platform.graphics.api.utils.SampledTexture;
import speiger.src.coreengine.platform.graphics.api.vertex.builder.IVertexBuffer.BufferResult;
import speiger.src.coreengine.platform.graphics.api.vertex.builder.IVertexBuilder;
import speiger.src.coreengine.platform.graphics.api.vertex.builder.VertexBuilder;
import speiger.src.coreengine.ui.gui.layout.box.IGuiBox;
import speiger.src.coreengine.ui.gui.utils.Align;
import speiger.src.coreengine.ui.gui.utils.UIConstants;
public class UIRenderer implements IUIRenderer {
GraphicsDevice device;
Matrix4fStack matrix = new Matrix4fStack();
VertexBuilder builder = new VertexBuilder(100);
List<UIDraw> draws = new ObjectArrayList<>();
Align[] alignment = new Align[] { Align.CENTER, Align.CENTER };
ShaderPipeline currentPipeline;
SampledTexture currentTexture;
public UIRenderer(GraphicsDevice device) {
this.device = device;
}
@Override
public boolean isClipping(IGuiBox box) {
return false;
}
@Override
public void pushClip(IGuiBox box) {
}
@Override
public void popClip() {
}
@Override
public void pushTransform() {
matrix.push();
}
@Override
public void popTransform() {
matrix.pop();
}
@Override
public void translate(float z) {
matrix.translateZ(z);
}
@Override
public void translate(float x, float y) {
matrix.translate(x, y);
}
@Override
public void scale(float scale) {
matrix.scale(scale);
}
@Override
public void scale(float x, float y) {
matrix.scale(x, y, 1F);
}
@Override
public void rotate(Quaternion rotation) {
matrix.rotate(rotation);
}
@Override
public void align(Align vertical, Align horizontal) {
alignment[0] = vertical;
alignment[1] = horizontal;
}
@Override
public void alignV(Align align) {
alignment[0] = align;
}
@Override
public void alignH(Align align) {
alignment[1] = align;
}
@Override
public void pushLayer(LayerType type) {
}
@Override
public void popLayer() {
}
@Override
public void drawLine(float startX, float startY, float endX, float endY, float lineWidth, int color) {
ensureType(UIConstants.GUI, null);
float dx = endX - startX;
float dy = endY - startY;
float xOffset = alignment[0].align(dx);
float yOffset = alignment[1].align(dy);
float length = (float)Math.sqrt(dx*dx + dy*dy);
dx /= length;
dy /= length;
float px = -dy * (lineWidth * 0.5F);
float py = dx * (lineWidth * 0.5F);
float x1 = startX + px;
float y1 = startY + py;
float x2 = startX - px;
float y2 = startY - py;
float x3 = endX + px;
float y3 = endY + py;
float x4 = endX - px;
float y4 = endY - py;
pos(x3, y3, 0F, xOffset, yOffset).rgba(color);
pos(x2, y2, 0F, xOffset, yOffset).rgba(color);
pos(x1, y1, 0F, xOffset, yOffset).rgba(color);
pos(x4, y4, 0F, xOffset, yOffset).rgba(color);
pos(x2, y2, 0F, xOffset, yOffset).rgba(color);
pos(x3, y3, 0F, xOffset, yOffset).rgba(color);
}
@Override
public void drawFrame(IGuiBox box, int color) {
ensureType(UIConstants.GUI, null);
float xOffset = alignment[0].align(box.getWidth());
float yOffset = alignment[1].align(box.getHeight());
float minX = box.getMinX();
float minY = box.getMinY();
float maxX = box.getMaxX();
float maxY = box.getMaxY();
drawQuad(maxX-1F, minY, maxX, maxY, xOffset, yOffset, color);
drawQuad(minX, maxY-1F, maxX, maxY, xOffset, yOffset, color);
drawQuad(minX, minY, minX+1F, maxY, xOffset, yOffset, color);
drawQuad(minX, minY, maxX, minY+1F, xOffset, yOffset, color);
}
@Override
public void drawRect(IGuiBox box, int color) {
ensureType(UIConstants.GUI, null);
float xOffset = alignment[0].align(box.getWidth());
float yOffset = alignment[1].align(box.getHeight());
drawQuad(box.getMinX(), box.getMinY(), box.getMaxX(), box.getMaxY(), xOffset, yOffset, color);
}
@Override
public void drawImage(IGuiBox box, SampledTexture texture, int color) {
drawImage(box, texture, 0F, 0F, 1F, 1F, color);
}
@Override
public void drawImage(IGuiBox box, SampledTexture texture, float minU, float minV, float maxU, float maxV, int color) {
ensureType(UIConstants.GUI_TEXTURED, texture);
float xOff = alignment[0].align(box.getWidth());
float yOff = alignment[1].align(box.getHeight());
float minX = box.getMinX();
float minY = box.getMinY();
float maxX = box.getMaxX();
float maxY = box.getMaxY();
pos(minX, maxY, 0F, xOff, yOff).tex(minU, maxV).rgba(color);
pos(minX, minY, 0F, xOff, yOff).tex(minU, minV).rgba(color);
pos(maxX, maxY, 0F, xOff, yOff).tex(maxU, maxV).rgba(color);
pos(maxX, maxY, 0F, xOff, yOff).tex(maxU, maxV).rgba(color);
pos(minX, minY, 0F, xOff, yOff).tex(minU, minV).rgba(color);
pos(maxX, minY, 0F, xOff, yOff).tex(maxU, minV).rgba(color);
}
@Override
public void drawCustom(UIDrawer drawer) {
//TDOO ensure the draw type isn't present
drawer.buildVertecies(builder, matrix);
}
protected void drawQuad(float minX, float minY, float maxX, float maxY, float xOff, float yOff, int color) {
pos(minX, maxY, 0F, xOff, yOff).rgba(color);
pos(minX, minY, 0F, xOff, yOff).rgba(color);
pos(maxX, maxY, 0F, xOff, yOff).rgba(color);
pos(maxX, maxY, 0F, xOff, yOff).rgba(color);
pos(minX, minY, 0F, xOff, yOff).rgba(color);
pos(maxX, minY, 0F, xOff, yOff).rgba(color);
}
protected IVertexBuilder pos(float x, float y, float z, float xOff, float yOff) {
matrix.transformOffset(x - xOff, y - yOff, z, xOff, yOff, 0F, builder::pos);
return builder;
}
protected void ensureType(ShaderPipeline pipeline, SampledTexture texture) {
if(currentPipeline == pipeline && currentTexture == texture) return;
if(builder.hasVertecies()) {
draws.add(new UIDraw(currentPipeline, currentTexture, builder.finish()));
}
currentPipeline = pipeline;
currentTexture = texture;
}
protected record UIDraw(ShaderPipeline pipeline, SampledTexture texture, BufferResult result) {}
}
@@ -0,0 +1,15 @@
package speiger.src.coreengine.ui.gui.utils;
public enum Align {
START,
CENTER,
END;
public float align(float width) {
return switch(this) {
case START -> 0;
case CENTER -> width * 0.5F;
case END -> width;
};
}
}
@@ -0,0 +1,33 @@
package speiger.src.coreengine.ui.gui.utils;
import speiger.src.coreengine.assets.api.ID;
import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline;
import speiger.src.coreengine.platform.graphics.api.shader.states.GraphicsDataType;
import speiger.src.coreengine.platform.graphics.api.shader.states.ShaderType;
import speiger.src.coreengine.platform.graphics.api.texture.states.TextureType;
import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout;
import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout.Usage;
public class UIConstants {
public static final VertexLayout GUI_LAYOUT = VertexLayout.builder()
.element("pos", 0, 3, Usage.POS)
.element("color", 1, 4, Usage.COLOR, GraphicsDataType.BYTE)
.build();
public static final VertexLayout GUI_TEXTURED_LAYOUT = VertexLayout.builder()
.element("pos", 0, 3, Usage.POS)
.element("tex", 1, 2, Usage.UV)
.element("color", 2, 4, Usage.COLOR, GraphicsDataType.BYTE)
.build();
public static final ShaderPipeline GUI = ShaderPipeline.builder(ID.of("gui"))
.withStage(ShaderType.VERTEX, ID.of("shader/gui/guiVertex.txt"))
.withStage(ShaderType.FRAGMENT, ID.of("shader/gui/guiFragment.txt"))
.withFormat(GUI_LAYOUT)
.build();
public static final ShaderPipeline GUI_TEXTURED = ShaderPipeline.builder(ID.of("gui"))
.withStage(ShaderType.VERTEX, ID.of("shader/gui/guiVertex.txt"))
.withStage(ShaderType.FRAGMENT, ID.of("shader/gui/guiFragment.txt"))
.withTexture("texture", 0, 0, TextureType.TEXTURE_2D)
.withFormat(GUI_TEXTURED_LAYOUT)
.build();
}
@@ -24,6 +24,7 @@ import speiger.src.coreengine.platform.graphics.api.sampler.SamplerSettings;
import speiger.src.coreengine.platform.graphics.api.sampler.states.BorderMode;
import speiger.src.coreengine.platform.graphics.api.sampler.states.SampleMode;
import speiger.src.coreengine.platform.graphics.api.shader.ShaderPipeline;
import speiger.src.coreengine.platform.graphics.api.shader.states.DrawMode;
import speiger.src.coreengine.platform.graphics.api.shader.states.GraphicsDataType;
import speiger.src.coreengine.platform.graphics.api.shader.states.ShaderType;
import speiger.src.coreengine.platform.graphics.api.texture.Texture;
@@ -32,6 +33,7 @@ import speiger.src.coreengine.platform.graphics.api.texture.drawable.Drawable;
import speiger.src.coreengine.platform.graphics.api.texture.states.TextureFormat;
import speiger.src.coreengine.platform.graphics.api.texture.states.TextureType;
import speiger.src.coreengine.platform.graphics.api.utils.ExecutionType;
import speiger.src.coreengine.platform.graphics.api.utils.SampledTexture;
import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout;
import speiger.src.coreengine.platform.graphics.api.vertex.VertexLayout.Usage;
import speiger.src.coreengine.platform.graphics.api.vertex.builder.VertexBuilder;
@@ -84,7 +86,7 @@ public class NewRenderEngineTest {
.build();
VertexBuilder builder = new VertexBuilder(255);
builder.start(null, layout);
builder.start(DrawMode.TRIANGLES, layout);
builder.pos(-0.5F, -0.5F, 0).tex(0F, 1F).rgba(-1);
builder.pos(0.5F, -0.5F, 0).tex(1F, 1F).rgba(-1);
builder.pos(0.5F, 0.5F, 0).tex(1F, 0F).rgba(-1);
@@ -123,7 +125,7 @@ public class NewRenderEngineTest {
queue.begin()
.pipeline(pipeline)
.mesh(mesh)
.texture(0, texture, sampler)
.texture(0, new SampledTexture(texture, sampler))
.uniform(0, buffer)
.drawArrays(0, 6)
.end();
@@ -1,5 +1,5 @@
package speiger.src.coreengine.math.vector.matrix;
public interface ITransformOutput {
public void accept(float...output);
public void accept(float x, float y, float z);
}
@@ -16,7 +16,6 @@ public class Matrix4f {
public static final int PROPERTY_TRANSLATION = 1 << 2;
public static final int PROPERTY_SCALE = 1 << 3;
public static final int PROPERTY_ROTATION = 1 << 4;
private static final int PROPERTY_DEFAULT = 1;
public static final int M00 = 0;
public static final int M01 = 1;
@@ -137,13 +136,13 @@ public class Matrix4f {
}
public Matrix4f setIdentity() {
if(properties == PROPERTY_DEFAULT) return this;
if((properties & PROPERTY_IDENTITY) == PROPERTY_IDENTITY) return this;
Arrays.fill(data, 0F);
data[M00] = 1F;
data[M11] = 1F;
data[M22] = 1F;
data[M33] = 1F;
properties = PROPERTY_DEFAULT;
properties = PROPERTY_IDENTITY | PROPERTY_TRANSLATION | PROPERTY_AFFINE;
return this;
}
@@ -190,22 +189,9 @@ public class Matrix4f {
}
public Matrix4f flip() {
data[M00] = -data[M00];
data[M01] = -data[M01];
data[M02] = -data[M02];
data[M03] = -data[M03];
data[M10] = -data[M10];
data[M11] = -data[M11];
data[M12] = -data[M12];
data[M13] = -data[M13];
data[M20] = -data[M20];
data[M21] = -data[M21];
data[M22] = -data[M22];
data[M23] = -data[M23];
data[M30] = -data[M30];
data[M31] = -data[M31];
data[M32] = -data[M32];
data[M33] = -data[M33];
for(int i = 0;i<16;i++) {
data[i] = -data[i];
}
return evaluateProps();
}
@@ -215,42 +201,16 @@ public class Matrix4f {
}
public Matrix4f add(Matrix4f other) {
data[M00] += other.data[M00];
data[M01] += other.data[M01];
data[M02] += other.data[M02];
data[M03] += other.data[M03];
data[M10] += other.data[M10];
data[M11] += other.data[M11];
data[M12] += other.data[M12];
data[M13] += other.data[M13];
data[M20] += other.data[M20];
data[M21] += other.data[M21];
data[M22] += other.data[M22];
data[M23] += other.data[M23];
data[M30] += other.data[M30];
data[M31] += other.data[M31];
data[M32] += other.data[M32];
data[M33] += other.data[M33];
for(int i = 0;i<16;i++) {
data[i] += other.data[i];
}
return evaluateProps();
}
public Matrix4f sub(Matrix4f other) {
data[M00] -= other.data[M00];
data[M01] -= other.data[M01];
data[M02] -= other.data[M02];
data[M03] -= other.data[M03];
data[M10] -= other.data[M10];
data[M11] -= other.data[M11];
data[M12] -= other.data[M12];
data[M13] -= other.data[M13];
data[M20] -= other.data[M20];
data[M21] -= other.data[M21];
data[M22] -= other.data[M22];
data[M23] -= other.data[M23];
data[M30] -= other.data[M30];
data[M31] -= other.data[M31];
data[M32] -= other.data[M32];
data[M33] -= other.data[M33];
for(int i = 0;i<16;i++) {
data[i] -= other.data[i];
}
return evaluateProps();
}
@@ -371,6 +331,10 @@ public class Matrix4f {
data[M32] += z;
return evaluateProps();
}
if((properties & PROPERTY_ROTATION) == 0) {
data[M32] += data[M22] * z;
evaluateProps();
}
data[M30] += data[M20] * z;
data[M31] += data[M21] * z;
data[M32] += data[M22] * z;
@@ -385,6 +349,11 @@ public class Matrix4f {
data[M31] += y;
return evaluateProps();
}
if((properties & PROPERTY_ROTATION) == 0) {
data[M30] += data[M00] * x;
data[M31] += data[M11] * y;
evaluateProps();
}
data[M30] += data[M00] * x + data[M10] * y;
data[M31] += data[M01] * x + data[M11] * y;
data[M32] += data[M02] * x + data[M12] * y;
@@ -401,6 +370,12 @@ public class Matrix4f {
properties |= PROPERTY_TRANSLATION;
return evaluateProps();
}
if((properties & PROPERTY_ROTATION) == 0) {
data[M30] += data[M00] * x;
data[M31] += data[M11] * y;
data[M32] += data[M22] * z;
evaluateProps();
}
data[M30] += data[M00] * x + data[M10] * y + data[M20] * z;
data[M31] += data[M01] * x + data[M11] * y + data[M21] * z;
data[M32] += data[M02] * x + data[M12] * y + data[M22] * z;
@@ -614,28 +589,20 @@ public class Matrix4f {
return this;
}
public void transform(Vec4f input, FloatBuffer buffer) {
transform(input.x(), input.y(), input.z(), input.w(), buffer::put);
}
public void transform(Vec3f input, boolean position, FloatBuffer buffer) {
transform(input.x(), input.y(), input.z(), position, buffer::put);
}
public void transform(float x, float y, float z, float w, ITransformOutput output) {
public void transformOffset(float x, float y, float z, float xOff, float yOff, float zOff, ITransformOutput output) {
if((properties & PROPERTY_IDENTITY) != 0) {
output.accept(x, y, z, w);
output.accept(x + xOff, y + yOff, z + zOff);
return;
}
if((properties & PROPERTY_ROTATION) != 0) {
output.accept(fma(M00, M10, M20, M30, x, y, z, w), fma(M01, M11, M21, M31, x, y, z, w), fma(M02, M12, M22, M32, x, y, z, w), fma(M03, M13, M23, M33, x, y, z, w));
output.accept(fma(M00, M10, M20, M30, x, y, z, 1F) + xOff, fma(M01, M11, M21, M31, x, y, z, 1F) + yOff, fma(M02, M12, M22, M32, x, y, z, 1F) + zOff);
return;
}
if((properties & PROPERTY_SCALE) != 0) {
output.accept(Math.fma(data[M00], x, data[M30]), Math.fma(data[M01], y, data[M31]), Math.fma(data[M02], z, data[M32]), Math.fma(data[M03], w, data[M33]));
output.accept(Math.fma(data[M00], x, data[M30]) + xOff, Math.fma(data[M01], y, data[M31]) + yOff, Math.fma(data[M02], z, data[M32]) + zOff);
return;
}
output.accept(x + data[M30], y + data[M31], z + data[M32], w + data[M33]);
output.accept(x + data[M30] + xOff, y + data[M31] + yOff, z + data[M32] + zOff);
}
public void transform(float x, float y, float z, boolean pos, ITransformOutput output) {