SimpleJavaEngine/src/main/java/speiger/src/coreengine/rendering/gui/components/PieComponent.java

171 lines
4.5 KiB
Java

package speiger.src.coreengine.rendering.gui.components;
import java.util.List;
import java.util.function.Supplier;
import org.lwjgl.opengl.GL11;
import speiger.src.coreengine.math.MathUtils;
import speiger.src.coreengine.math.misc.ColorUtils;
import speiger.src.coreengine.rendering.gui.GuiComponent;
import speiger.src.coreengine.rendering.gui.renderer.buffer.RenderBuffer;
import speiger.src.coreengine.rendering.tesselation.Tesselator;
import speiger.src.coreengine.rendering.tesselation.VertexType;
import speiger.src.coreengine.rendering.utils.GLUtils;
public class PieComponent extends GuiComponent
{
public static final int FLAG_AUTO_UPDATE = 1 << 20;
RenderBuffer buffer;
Supplier<List<IPieIndex>> parts;
int maxSteps;
public PieComponent(int maxSteps, Supplier<List<IPieIndex>> parts)
{
super(0F, 0F, 0F, 0F);
this.maxSteps = maxSteps;
this.parts = parts;
}
public PieComponent(float x, float y, float width, float height, int maxSteps, Supplier<List<IPieIndex>> parts)
{
super(x, y, width, height);
this.maxSteps = maxSteps;
this.parts = parts;
}
@Override
public void init()
{
addCloseListener(buffer = getRenderer().createBuffer());
}
public final PieComponent setAutoUpdate(boolean value)
{
setFlag(FLAG_AUTO_UPDATE, value);
return this;
}
public final boolean isAutoUpdating()
{
return isFlagSet(FLAG_AUTO_UPDATE);
}
public int getMaxSteps()
{
return maxSteps;
}
@Override
protected boolean fixedUpdateSelf()
{
if(isAutoUpdating())
{
createPie();
}
return true;
}
@Override
protected void repaint()
{
createPie();
}
@Override
protected boolean renderSelf(int mouseX, int mouseY, float particalTicks)
{
float centerX = getBox().getCenterX();
float centerY = getBox().getCenterY();
getRenderer().setBrightness(getActiveBrightness()).translate(centerX, centerY).flush();
GLUtils.DEBTH_TEST.push(true);
getRenderer().drawBuffers(buffer, 0F, 0F).flush();
GLUtils.DEBTH_TEST.pop();
getRenderer().translate(-centerX, -centerY).setBrightness(1F);
return true;
}
protected void createPie()
{
buffer.clear();
if(parts == null)
{
return;
}
float xSize = getBox().getWidth() / 2F;
float ySize = getBox().getHeight() / 2F;
float extra = getBox().getHeight() / 10F;
float value = -3.17F;
float spaceScale = 0.0495F * (127.0F / maxSteps);
List<IPieIndex> indexes = parts.get();
int stepsDone = 0;
Tesselator tes = buffer.start(GL11.GL_TRIANGLES, VertexType.UI);
for(int j = indexes.size()-1;j>=0;j--)
{
IPieIndex pieIndex = indexes.get(j);
int steps = j == 0 ? maxSteps - stepsDone : pieIndex.getSteps();
int color = pieIndex.getColor();
int darker = ColorUtils.darker(color);
tes.offset(0F, 0F, 0.01F);
for(int i = 0;i<steps;i++)
{
int index = i + stepsDone;
tes.pos(0F, 0F, 0F).tex(0F, 0F).color4f(color).endVertex();
tes.pos(MathUtils.sin(value + spaceScale * index) * xSize, MathUtils.cos(value + spaceScale * index) * ySize * 0.5F, 0F).tex(0F, 0F).color4f(color).endVertex();
index++;
tes.pos(MathUtils.sin(value + spaceScale * index) * xSize, MathUtils.cos(value + spaceScale * index) * ySize * 0.5F, 0F).tex(0F, 0F).color4f(color).endVertex();
}
tes.offset(0F, 0F, -0.01F);
for(int i = 0;i<steps;i++)
{
int index = i + stepsDone;
float x = MathUtils.sin(value + spaceScale * index) * xSize;
float y = MathUtils.cos(value + spaceScale * index) * ySize * 0.5F;
tes.pos(x, y, 0F).tex(0F, 0F).color4f(darker).endVertex();
index++;
float nextX = MathUtils.sin(value + spaceScale * index) * xSize;
float nextY = MathUtils.cos(value + spaceScale * index) * ySize * 0.5F;
tes.pos(nextX, nextY + extra, 0F).tex(0F, 0F).color4f(darker).endVertex();
tes.pos(x, y + extra, 0F).tex(0F, 0F).color4f(darker).endVertex();
tes.pos(nextX, nextY, 0F).tex(0F, 0F).color4f(darker).endVertex();
tes.pos(nextX, nextY + extra, 0F).tex(0F, 0F).color4f(darker).endVertex();
tes.pos(x, y, 0F).tex(0F, 0F).color4f(darker).endVertex();
}
stepsDone += steps;
}
buffer.finishShape(0);
}
public static interface IPieIndex
{
public int getSteps();
public int getColor();
}
public static class PieIndex implements IPieIndex
{
int steps;
int color;
public PieIndex(int steps, int color)
{
this.steps = steps;
this.color = color;
}
@Override
public int getSteps()
{
return steps;
}
@Override
public int getColor()
{
return color;
}
}
}