713 lines
22 KiB
Java
713 lines
22 KiB
Java
package speiger.src.coreengine.rendering.gui.renderer;
|
|
|
|
import java.nio.ByteBuffer;
|
|
import java.nio.ByteOrder;
|
|
import java.nio.FloatBuffer;
|
|
|
|
import org.lwjgl.opengl.GL11;
|
|
import org.lwjgl.system.MemoryUtil;
|
|
|
|
import speiger.src.collections.objects.lists.ObjectArrayList;
|
|
import speiger.src.collections.objects.queues.ObjectArrayFIFOQueue;
|
|
import speiger.src.collections.objects.queues.ObjectPriorityDequeue;
|
|
import speiger.src.collections.utils.Stack;
|
|
import speiger.src.coreengine.assets.reloader.IReloadableResource;
|
|
import speiger.src.coreengine.math.misc.Facing;
|
|
import speiger.src.coreengine.math.vector.floats.Vec2f;
|
|
import speiger.src.coreengine.math.vector.floats.Vec3f;
|
|
import speiger.src.coreengine.math.vector.floats.Vec4f;
|
|
import speiger.src.coreengine.math.vector.matrix.Matrix4f;
|
|
import speiger.src.coreengine.math.vector.quaternion.Quaternion;
|
|
import speiger.src.coreengine.rendering.gui.GuiManager;
|
|
import speiger.src.coreengine.rendering.gui.helper.Align;
|
|
import speiger.src.coreengine.rendering.gui.helper.box.IGuiBox;
|
|
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
|
|
import speiger.src.coreengine.rendering.models.DrawCall;
|
|
import speiger.src.coreengine.rendering.shader.uniforms.UniformVec2f;
|
|
import speiger.src.coreengine.rendering.tesselation.GLCall;
|
|
import speiger.src.coreengine.rendering.tesselation.Tesselator;
|
|
import speiger.src.coreengine.rendering.tesselation.VertexType;
|
|
import speiger.src.coreengine.rendering.textures.base.ITexture;
|
|
import speiger.src.coreengine.rendering.textures.base.TextureManager;
|
|
import speiger.src.coreengine.rendering.utils.GLUtils;
|
|
import speiger.src.coreengine.utils.collections.pools.SimplePool;
|
|
|
|
public class UIRenderer implements IReloadableResource
|
|
{
|
|
SimplePool<Matrix4f> recylcePool = new SimplePool<>(100, Matrix4f::new);
|
|
Stack<Matrix4f> transformStack = new ObjectArrayList<>();
|
|
Matrix4f transform = new Matrix4f();
|
|
boolean isFastTransform = true;
|
|
SimplePool<Vec4f> fastPool = new SimplePool<>(100, () -> Vec4f.newMutable(0F, 0F, 0F, 1F));
|
|
Stack<Vec4f> fastStack = new ObjectArrayList<>();
|
|
Vec4f fastTransform = Vec4f.newMutable(0F, 0F, 0F, 1F);
|
|
|
|
SimplePool<GLCall> callPool = new SimplePool<>(100, GLCall::new);
|
|
ObjectPriorityDequeue<GLCall> activeCalls = new ObjectArrayFIFOQueue<>();
|
|
|
|
Tesselator bufferHelper = new Tesselator(655340);
|
|
FloatBuffer renderBuffer = MemoryUtil.memAllocFloat(655340);
|
|
Tesselator renderer = new Tesselator(renderBuffer);
|
|
ITexture currentTexture;
|
|
boolean drawing = false;
|
|
boolean useTexture = false;
|
|
Vec4f currentFrame = Vec4f.newMutable();
|
|
float roundedNess = 0F;
|
|
|
|
GuiModel texturedModel = GuiModel.createTextureModel(Short.MAX_VALUE * 2);
|
|
|
|
Align horizontal = Align.CENTER;
|
|
Align vertical = Align.CENTER;
|
|
|
|
Vec3f helper = Vec3f.newMutable();
|
|
Vec4f transformHelper = Vec4f.newMutable();
|
|
Vec4f alignHelper = Vec4f.newMutable();
|
|
Vec3f alignTranslation = Vec3f.newMutable(0F);
|
|
Vec3f alignScale = Vec3f.newMutable(1F);
|
|
|
|
GuiManager manager;
|
|
|
|
public UIRenderer(GuiManager manager)
|
|
{
|
|
this.manager = manager;
|
|
TextureManager.INSTANCE.getReloader().addReloadableResource(this);
|
|
}
|
|
|
|
public RenderBuffer createBuffer()
|
|
{
|
|
return new RenderBuffer(bufferHelper);
|
|
}
|
|
|
|
public UIRenderer push()
|
|
{
|
|
if(isFastTransform)
|
|
{
|
|
fastStack.push(fastPool.get().set(fastTransform));
|
|
return this;
|
|
}
|
|
transformStack.push(recylcePool.get().load(transform));
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer pop()
|
|
{
|
|
if(isFastTransform)
|
|
{
|
|
Vec4f pop = fastStack.pop();
|
|
fastTransform.set(pop);
|
|
fastPool.accept(pop);
|
|
return this;
|
|
}
|
|
Matrix4f pop = transformStack.pop();
|
|
transform.load(pop);
|
|
pop.getScale(alignScale);
|
|
recylcePool.accept(pop);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer setVisibility(float visibility)
|
|
{
|
|
sanityCheck("Visibilty Change");
|
|
renderer.setVisibilty(visibility);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer setBrightness(float brightness)
|
|
{
|
|
sanityCheck("Brightness change");
|
|
renderer.setBrightness(brightness);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer resetEffects()
|
|
{
|
|
renderer.setBrightness(1F).setVisibilty(1F);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer setActiveTexture(ITexture texture)
|
|
{
|
|
if(getTextureId(currentTexture) != getTextureId(texture))
|
|
{
|
|
addDrawCall();
|
|
currentTexture = texture;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer setRoundness(IGuiBox box, float roundedNess)
|
|
{
|
|
if(roundedNess <= 0)
|
|
{
|
|
if(this.roundedNess > 0F) addDrawCall();
|
|
this.roundedNess = roundedNess;
|
|
return this;
|
|
}
|
|
alignHelper.set(box.getMinX(), box.getMinY(), box.getMaxX(), box.getMaxY());
|
|
if(!currentFrame.equals(alignHelper) || this.roundedNess != roundedNess)
|
|
{
|
|
addDrawCall();
|
|
currentFrame.set(alignHelper);
|
|
this.roundedNess = roundedNess;
|
|
}
|
|
return this;
|
|
}
|
|
|
|
protected void applyEffects(UniformVec2f vec)
|
|
{
|
|
vec.storeData(renderer.getBrightness(), renderer.getVisibility());
|
|
}
|
|
|
|
public UIRenderer translate(float x, float y)
|
|
{
|
|
return translate(x, y, 0F);
|
|
}
|
|
|
|
public UIRenderer translate(Vec2f offset)
|
|
{
|
|
return translate(offset.getX(), offset.getY(), 0F);
|
|
}
|
|
|
|
public UIRenderer translate(float x, float y, float z)
|
|
{
|
|
if(isFastTransform)
|
|
{
|
|
fastTransform.add(x, y, z, 0F);
|
|
return this;
|
|
}
|
|
transform.translate(helper.set(x, y, z));
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer translate(Vec3f offset)
|
|
{
|
|
if(isFastTransform)
|
|
{
|
|
fastTransform.add(offset.getX(), offset.getY(), offset.getZ(), 0F);
|
|
return this;
|
|
}
|
|
transform.translate(offset);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer rotate(Quaternion quad)
|
|
{
|
|
if(isFastTransform) return this;
|
|
transform.rotate(quad);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer rotateX(float angle)
|
|
{
|
|
if(isFastTransform) return this;
|
|
transform.rotateX((float)Math.toRadians(angle));
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer rotateY(float angle)
|
|
{
|
|
if(isFastTransform) return this;
|
|
transform.rotateY((float)Math.toRadians(angle));
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer rotateZ(float angle)
|
|
{
|
|
if(isFastTransform) return this;
|
|
transform.rotateZ((float)Math.toRadians(angle));
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer scale(float x, float y, float z)
|
|
{
|
|
if(isFastTransform) return this;
|
|
transform.scale(helper.set(x, y, z));
|
|
alignScale.multiply(x, y, z);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer scale(float scale)
|
|
{
|
|
if(isFastTransform)
|
|
{
|
|
fastTransform.multiply(1F, 1F, 1F, scale);
|
|
return this;
|
|
}
|
|
transform.scale(helper.set(scale, scale, scale));
|
|
alignScale.multiply(scale);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer unscale(float x, float y, float z)
|
|
{
|
|
if(isFastTransform) return this;
|
|
transform.scale(helper.set(1.0F / x, 1.0F / y, 1.0F / z));
|
|
alignScale.multiply(helper);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer unscale(float scale)
|
|
{
|
|
scale = 1.0F / scale;
|
|
if(isFastTransform)
|
|
{
|
|
fastTransform.multiply(1F, 1F, 1F, scale);
|
|
return this;
|
|
}
|
|
transform.scale(helper.set(scale, scale, scale)).getScale(alignScale);
|
|
alignScale.multiply(scale);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer resetTransform()
|
|
{
|
|
if(isFastTransform)
|
|
{
|
|
fastTransform.set(0F, 0F, 0F, 1F);
|
|
return this;
|
|
}
|
|
transform.setIdentity();
|
|
alignScale.set(Vec3f.ONE);
|
|
return this;
|
|
}
|
|
|
|
public float getCurrentZ()
|
|
{
|
|
return isFastTransform ? fastTransform.getZ() : transform.get(3, 2);
|
|
}
|
|
|
|
public ITexture getActiveTexture()
|
|
{
|
|
return currentTexture;
|
|
}
|
|
|
|
protected Matrix4f getCurrentMatrix()
|
|
{
|
|
return transform;
|
|
}
|
|
|
|
public Matrix4f createCurrentMatrix(Matrix4f matrix)
|
|
{
|
|
return isFastTransform ? matrix.setIdentity().translate(fastTransform.getX(), fastTransform.getY(), fastTransform.getZ()) : matrix.load(transform);
|
|
}
|
|
|
|
public UIRenderer setFastTransform(boolean fast)
|
|
{
|
|
isFastTransform = fast;
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer beginFrame()
|
|
{
|
|
if(drawing)
|
|
{
|
|
throw new RuntimeException("Already Drawing!");
|
|
}
|
|
drawing = true;
|
|
fastTransform.set(0F, 0F, 0F, 1F);
|
|
roundedNess = 0F;
|
|
currentFrame.negate();
|
|
transform.setIdentity();
|
|
alignScale.set(Vec3f.ONE);
|
|
transformStack.clear();
|
|
fastStack.clear();
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer flush()
|
|
{
|
|
if(!renderer.isDrawing())
|
|
{
|
|
return this;
|
|
}
|
|
renderer.finishData();
|
|
int count = renderer.getVertexCount();
|
|
if(count <= 0)
|
|
{
|
|
return this;
|
|
}
|
|
if(count > (activeCalls.isEmpty() ? 0 : activeCalls.last().getCount()))
|
|
{
|
|
addDrawCall();
|
|
}
|
|
texturedModel.storeData(renderBuffer);
|
|
GuiShader shader = manager.getShader();
|
|
shader.bind(manager.getOrthoMatrixBuffer());
|
|
texturedModel.bindArray();
|
|
int last = 0;
|
|
while(!activeCalls.isEmpty())
|
|
{
|
|
GLCall call = activeCalls.dequeue();
|
|
shader.texture.storeTexture(call.getTexture());
|
|
shader.useTexture.storeData(call.getTexture() > 0 ? 1F : 0F);
|
|
shader.roundeness.storeData(call.getRoundedNess());
|
|
if(call.getRoundedNess() > 0F) shader.bounds.storeData(call.getFrame());
|
|
GLUtils.drawArrays(call.getType(), last, call.getCount() - last);
|
|
last = call.getCount();
|
|
callPool.accept(call);
|
|
}
|
|
activeCalls.clear();
|
|
texturedModel.unbindArray();
|
|
shader.stopShader();
|
|
renderer.resetVertexes();
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer endFrame()
|
|
{
|
|
if(!drawing)
|
|
{
|
|
throw new RuntimeException("Not Drawing!");
|
|
}
|
|
drawing = false;
|
|
isFastTransform = true;
|
|
flush();
|
|
fastTransform.set(0F, 0F, 0F, 1F);
|
|
transform.setIdentity();
|
|
renderer.resetEffects();
|
|
useTexture = false;
|
|
while(!transformStack.isEmpty())
|
|
{
|
|
recylcePool.accept(transformStack.pop());
|
|
}
|
|
while(!fastStack.isEmpty())
|
|
{
|
|
fastPool.accept(fastStack.pop());
|
|
}
|
|
return this;
|
|
}
|
|
|
|
@Override
|
|
public void reload()
|
|
{
|
|
texturedModel.remove();
|
|
MemoryUtil.memFree(renderBuffer);
|
|
texturedModel = GuiModel.createTextureModel(Short.MAX_VALUE * 2);
|
|
renderBuffer = MemoryUtil.memAllocFloat(655340);
|
|
renderer = new Tesselator(renderBuffer);
|
|
}
|
|
|
|
@Override
|
|
public void destroy()
|
|
{
|
|
texturedModel.remove();
|
|
MemoryUtil.memFree(renderBuffer);
|
|
TextureManager.INSTANCE.getReloader().removeReloadableResource(this);
|
|
}
|
|
|
|
public UIRenderer drawBuffers(Iterable<DrawCall> drawCalls, float width, float height)
|
|
{
|
|
sanityCheck("Buffer Drawing");
|
|
applyAlignment(0, 0, width, height, 0, alignHelper);
|
|
for(DrawCall call : drawCalls)
|
|
{
|
|
ensureDrawing(call.getGLType(), call.getTextureId() > 0);
|
|
FloatBuffer buffer = ByteBuffer.wrap(call.getData()).order(ByteOrder.nativeOrder()).asFloatBuffer();
|
|
for(int i = 0,m=buffer.remaining();i+9<=m;i+=9)
|
|
{
|
|
pos(transformHelper.set(buffer.get(i)+alignHelper.getX(), buffer.get(i+1)+alignHelper.getY(), buffer.get(i+2), 1F))
|
|
.tex(buffer.get(i+3), buffer.get(i+4))
|
|
.color4f(buffer.get(i+5), buffer.get(i+6), buffer.get(i+7), buffer.get(i+8)).endVertex();
|
|
}
|
|
}
|
|
alignTranslation.set(0F, 0F, 0F);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer drawQuad(IGuiBox box, int color)
|
|
{
|
|
return drawQuad(box.getMinX(), box.getMinY(), box.getMaxX(), box.getMaxY(), color);
|
|
}
|
|
|
|
public UIRenderer drawQuad(IGuiBox box, float zLevel, int color)
|
|
{
|
|
return drawQuad(box.getMinX(), box.getMinY(), box.getMaxX(), box.getMaxY(), zLevel, color);
|
|
}
|
|
|
|
public UIRenderer drawQuad(float minX, float minY, float maxX, float maxY, int color)
|
|
{
|
|
return drawQuad(minX, minY, maxX, maxY, 0.0F, color);
|
|
}
|
|
|
|
public UIRenderer drawQuad(float minX, float minY, float maxX, float maxY, float zLevel, int color)
|
|
{
|
|
ensureDrawing(GL11.GL_TRIANGLES, false);
|
|
applyAlignment(minX, minY, maxX, maxY, zLevel, alignHelper);
|
|
pos(transformHelper.set(alignHelper.getX(), alignHelper.getW(), 0F, 1F)).tex(0F, 0F).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getX(), alignHelper.getY(), 0F, 1F)).tex(0F, 0F).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getZ(), alignHelper.getW(), 0F, 1F)).tex(0F, 0F).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getZ(), alignHelper.getW(), 0F, 1F)).tex(0F, 0F).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getX(), alignHelper.getY(), 0F, 1F)).tex(0F, 0F).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getZ(), alignHelper.getY(), 0F, 1F)).tex(0F, 0F).color4f(color).endVertex();
|
|
alignTranslation.set(0F, 0F, 0F);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer drawTexturedQuad(IGuiBox box, int color, float minU, float minV, float maxU, float maxV)
|
|
{
|
|
return drawTexturedQuad(box.getMinX(), box.getMinY(), box.getMaxX(), box.getMaxY(), color, minU, minV, maxU, maxV);
|
|
}
|
|
|
|
public UIRenderer drawTexturedQuad(IGuiBox box, float zLevel, int color, float minU, float minV, float maxU, float maxV)
|
|
{
|
|
return drawTexturedQuad(box.getMinX(), box.getMinY(), box.getMaxX(), box.getMaxY(), zLevel, color, minU, minV, maxU, maxV);
|
|
}
|
|
|
|
public UIRenderer drawTexturedQuad(float minX, float minY, float maxX, float maxY, int color, float minU, float minV, float maxU, float maxV)
|
|
{
|
|
return drawTexturedQuad(minX, minY, maxX, maxY, 0F, color, minU, minV, maxU, maxV);
|
|
}
|
|
|
|
public UIRenderer drawTexturedQuad(float minX, float minY, float maxX, float maxY, float zLevel, int color, float minU, float minV, float maxU, float maxV)
|
|
{
|
|
ensureDrawing(GL11.GL_TRIANGLES, true);
|
|
applyAlignment(minX, minY, maxX, maxY, zLevel, alignHelper);
|
|
pos(transformHelper.set(alignHelper.getX(), alignHelper.getW(), 0F, 1F)).tex(minU, maxV).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getX(), alignHelper.getY(), 0F, 1F)).tex(minU, minV).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getZ(), alignHelper.getW(), 0F, 1F)).tex(maxU, maxV).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getZ(), alignHelper.getW(), 0F, 1F)).tex(maxU, maxV).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getX(), alignHelper.getY(), 0F, 1F)).tex(minU, minV).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getZ(), alignHelper.getY(), 0F, 1F)).tex(maxU, minV).color4f(color).endVertex();
|
|
alignTranslation.set(0F, 0F, 0F);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer drawGradientQuad(IGuiBox box, int from, int to, Facing direction)
|
|
{
|
|
return drawGradientQuad(box.getMinX(), box.getMinY(), box.getMaxX(), box.getMaxY(), from, to, direction);
|
|
}
|
|
|
|
public UIRenderer drawGradientQuad(float minX, float minY, float maxX, float maxY, int from, int to, Facing direction)
|
|
{
|
|
return drawGradientQuad(minX, minY, maxX, maxY, 0F, from, to, direction);
|
|
}
|
|
|
|
public UIRenderer drawGradientQuad(float minX, float minY, float maxX, float maxY, float zLevel, int start, int end, Facing direction)
|
|
{
|
|
if(!direction.isPositive())
|
|
{
|
|
int wrapper = start;
|
|
start = end;
|
|
end = wrapper;
|
|
}
|
|
ensureDrawing(GL11.GL_TRIANGLES, false);
|
|
applyAlignment(minX, minY, maxX, maxY, zLevel, alignHelper);
|
|
pos(transformHelper.set(alignHelper.getX(), alignHelper.getW(), 0F, 1F)).tex(0F, 0F).color4f(direction.isXAxis() ? start : end).endVertex();
|
|
pos(transformHelper.set(alignHelper.getX(), alignHelper.getY(), 0F, 1F)).tex(0F, 0F).color4f(direction.isXAxis() ? start : start).endVertex();
|
|
pos(transformHelper.set(alignHelper.getZ(), alignHelper.getW(), 0F, 1F)).tex(0F, 0F).color4f(direction.isXAxis() ? end : end).endVertex();
|
|
pos(transformHelper.set(alignHelper.getZ(), alignHelper.getW(), 0F, 1F)).tex(0F, 0F).color4f(direction.isXAxis() ? end : end).endVertex();
|
|
pos(transformHelper.set(alignHelper.getX(), alignHelper.getY(), 0F, 1F)).tex(0F, 0F).color4f(direction.isXAxis() ? start : start).endVertex();
|
|
pos(transformHelper.set(alignHelper.getZ(), alignHelper.getY(), 0F, 1F)).tex(0F, 0F).color4f(direction.isXAxis() ? end : start).endVertex();
|
|
alignTranslation.set(0F, 0F, 0F);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer drawFrame(IGuiBox box, int color)
|
|
{
|
|
return drawFrame(box.getMinX(), box.getMinY(), box.getMaxX(), box.getMaxY(), color);
|
|
}
|
|
|
|
public UIRenderer drawFrame(IGuiBox box, float zLevel, int color)
|
|
{
|
|
return drawFrame(box.getMinX(), box.getMinY(), box.getMaxX(), box.getMaxY(), zLevel, color);
|
|
}
|
|
|
|
public UIRenderer drawFrame(float minX, float minY, float maxX, float maxY, int color)
|
|
{
|
|
return drawFrame(minX, minY, maxX, maxY, 0F, color);
|
|
}
|
|
|
|
public UIRenderer drawFrame(float minX, float minY, float maxX, float maxY, float zLevel, int color)
|
|
{
|
|
ensureDrawing(GL11.GL_LINES, false);
|
|
applyAlignment(minX, minY, maxX, maxY, zLevel, alignHelper);
|
|
pos(transformHelper.set(alignHelper.getX(), alignHelper.getY(), 0F, 1F)).tex(0F, 0F).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getZ(), alignHelper.getY(), 0F, 1F)).tex(0F, 0F).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getZ(), alignHelper.getY(), 0F, 1F)).tex(0F, 0F).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getZ(), alignHelper.getW(), 0F, 1F)).tex(0F, 0F).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getZ(), alignHelper.getW(), 0F, 1F)).tex(0F, 0F).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getX(), alignHelper.getW(), 0F, 1F)).tex(0F, 0F).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getX(), alignHelper.getW(), 0F, 1F)).tex(0F, 0F).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getX(), alignHelper.getY(), 0F, 1F)).tex(0F, 0F).color4f(color).endVertex();
|
|
alignTranslation.set(0F, 0F, 0F);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer drawLine(float minX, float minY, float maxX, float maxY, int color)
|
|
{
|
|
return drawLine(minX, minY, maxX, maxY, 0F, color);
|
|
}
|
|
|
|
public UIRenderer drawLine(float minX, float minY, float maxX, float maxY, float zLevel, int color)
|
|
{
|
|
ensureDrawing(GL11.GL_LINES, false);
|
|
applyAlignment(minX, minY, maxX, maxY, zLevel, alignHelper);
|
|
pos(transformHelper.set(alignHelper.getX(), alignHelper.getY(), 0F, 1F)).tex(0F, 0F).color4f(color).endVertex();
|
|
pos(transformHelper.set(alignHelper.getZ(), alignHelper.getW(), 0F, 1F)).tex(0F, 0F).color4f(color).endVertex();
|
|
alignTranslation.set(0F, 0F, 0F);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer startCustomShape(int shapeType, boolean needsTexture)
|
|
{
|
|
sanityCheck("Custom Shape");
|
|
ensureDrawing(shapeType, needsTexture);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer pos(float x, float y, float z)
|
|
{
|
|
pos(transformHelper.set(x, y, z, 1F));
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer pos(Vec3f pos)
|
|
{
|
|
return pos(pos.getX(), pos.getY(), pos.getZ());
|
|
}
|
|
|
|
public UIRenderer color(float r, float g, float b)
|
|
{
|
|
renderer.color4f(r, g, b);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer color(float r, float g, float b, float a)
|
|
{
|
|
renderer.color4f(r, g, b, a);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer color(int color)
|
|
{
|
|
renderer.color4f(color);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer tex(float u, float v)
|
|
{
|
|
renderer.tex(u, v);
|
|
return this;
|
|
}
|
|
|
|
public UIRenderer tex(Vec2f tex)
|
|
{
|
|
return tex(tex.getX(), tex.getY());
|
|
}
|
|
|
|
public UIRenderer endVertex()
|
|
{
|
|
renderer.endVertex();
|
|
return this;
|
|
}
|
|
|
|
protected void sanityCheck(String task)
|
|
{
|
|
if(drawing)
|
|
{
|
|
return;
|
|
}
|
|
throw new RuntimeException(task);
|
|
}
|
|
|
|
protected Tesselator pos(Vec4f pos)
|
|
{
|
|
if(isFastTransform)
|
|
{
|
|
return renderer.pos(fastTransform(pos.getX(), fastTransform.getX(), alignTranslation.getX()), fastTransform(pos.getY(), fastTransform.getY(), alignTranslation.getY()), fastTransform(pos.getZ(), fastTransform.getZ(), alignTranslation.getZ()));
|
|
}
|
|
float x = (transform.get(0) * pos.getX() + transform.get(4) * pos.getY() + transform.get(8) * pos.getZ() + transform.get(12)) + (alignTranslation.getX() * alignScale.getX());
|
|
float y = (transform.get(1) * pos.getX() + transform.get(5) * pos.getY() + transform.get(9) * pos.getZ() + transform.get(13)) + (alignTranslation.getY() * alignScale.getY());
|
|
float z = (transform.get(2) * pos.getX() + transform.get(6) * pos.getY() + transform.get(10) * pos.getZ() + transform.get(14)) + (alignTranslation.getZ() * alignScale.getZ());
|
|
return renderer.pos(x, y, z);
|
|
}
|
|
|
|
private float fastTransform(float pos, float offset, float align)
|
|
{
|
|
return ((pos + align) * fastTransform.getW()) + offset;
|
|
}
|
|
|
|
protected void applyAlignment(float minX, float minY, float maxX, float maxY, float zLevel, Vec4f result)
|
|
{
|
|
applyAlignment(minX, minY, maxX, maxY, zLevel, vertical, horizontal, renderer, result);
|
|
}
|
|
|
|
protected void applyAlignment(float minX, float minY, float maxX, float maxY, float zLevel, Align vertical, Align horizontal, Tesselator tes, Vec4f result)
|
|
{
|
|
float width = maxX - minX;
|
|
float height = maxY - minY;
|
|
float xOffset = 0F;
|
|
float yOffset = 0F;
|
|
switch(vertical)
|
|
{
|
|
case LEFT_TOP:
|
|
yOffset = 0;
|
|
result.setY(0F).setW(height);
|
|
break;
|
|
case CENTER:
|
|
yOffset = height / 2F;
|
|
result.setY(-yOffset).setW(yOffset);
|
|
break;
|
|
case RIGHT_BOTTOM:
|
|
yOffset = maxY;
|
|
result.setY(-height).setW(0F);
|
|
break;
|
|
}
|
|
switch(horizontal)
|
|
{
|
|
case LEFT_TOP:
|
|
xOffset = 0;
|
|
result.setX(0F).setZ(width);
|
|
break;
|
|
case CENTER:
|
|
xOffset = width / 2F;
|
|
result.setX(-xOffset).setZ(xOffset);
|
|
break;
|
|
case RIGHT_BOTTOM:
|
|
xOffset = maxX;
|
|
result.setX(-width).setZ(0F);
|
|
break;
|
|
}
|
|
alignTranslation.set(minX + xOffset, minY + yOffset, zLevel);
|
|
}
|
|
|
|
protected void ensureDrawing(int glState, boolean textureNeeded)
|
|
{
|
|
if(!renderer.isDrawing())
|
|
{
|
|
renderer.begin(glState, VertexType.UI);
|
|
}
|
|
if(glState != renderer.getGLDrawType() || useTexture != textureNeeded)
|
|
{
|
|
addDrawCall();
|
|
renderer.changeGLType(glState);
|
|
useTexture = textureNeeded;
|
|
}
|
|
}
|
|
|
|
protected void addDrawCall()
|
|
{
|
|
if(getDrawCall() >= renderer.getVertexCount())
|
|
{
|
|
return;
|
|
}
|
|
GLCall call = callPool.get();
|
|
call.setType(renderer.getGLDrawType());
|
|
call.setCount(renderer.getVertexCount());
|
|
call.setTexture(getTextureId(useTexture ? currentTexture : null));
|
|
call.setFrame(currentFrame);
|
|
call.setRounded(roundedNess);
|
|
activeCalls.enqueue(call);
|
|
}
|
|
|
|
private int getDrawCall()
|
|
{
|
|
return activeCalls.isEmpty() ? 0 : activeCalls.last().getCount();
|
|
}
|
|
|
|
private int getTextureId(ITexture texture)
|
|
{
|
|
return texture == null ? 0 : texture.getTextureId();
|
|
}
|
|
}
|