SimpleJavaEngine/src/main/java/speiger/src/coreengine/rendering/tesselation/Tesselator.java

277 lines
5.4 KiB
Java

package speiger.src.coreengine.rendering.tesselation;
import java.nio.FloatBuffer;
import speiger.src.coreengine.math.vector.floats.Vec2f;
import speiger.src.coreengine.math.vector.floats.Vec3f;
import speiger.src.coreengine.rendering.models.DrawCall;
import speiger.src.coreengine.rendering.tesselation.VertexElement.ElementUsage;
public class Tesselator implements IVertexBuilder
{
boolean drawing = false;
int drawType = 0;
VertexList currentList;
VertexElement currentElement;
int currentIndex = 0;
Vec3f offset = Vec3f.mutable();
Vec2f effects = Vec2f.mutable(1F);
FloatBuffer buffer;
int vertexes = 0;
public Tesselator(int capacity)
{
buffer = FloatBuffer.allocate(capacity);
}
public Tesselator(FloatBuffer buffer)
{
this.buffer = buffer;
}
public Tesselator begin(int glType, VertexList list)
{
if(drawing)
{
throw new RuntimeException("Already Drawing");
}
drawType = glType;
drawing = true;
currentList = list;
currentElement = list.get(0);
currentIndex = 0;
buffer.clear();
vertexes = 0;
return this;
}
public Tesselator changeGLType(int glType)
{
if(!drawing)
{
throw new RuntimeException("Can not change type");
}
drawType = glType;
return this;
}
public Tesselator resetVertexes()
{
vertexes = 0;
return this;
}
public Tesselator setBrightness(float value)
{
effects.setX(value);
return this;
}
public Tesselator setVisibilty(float value)
{
effects.setY(value);
return this;
}
public float getBrightness()
{
return effects.getX();
}
public float getVisibility()
{
return effects.getY();
}
public Tesselator resetEffects()
{
effects.set(Vec2f.ONE);
return this;
}
public Tesselator offset(float x, float y, float z)
{
offset.add(x, y, z);
return this;
}
public Tesselator setOffset(float x, float y, float z)
{
offset.set(x, y, z);
return this;
}
@Override
public Tesselator pos(float x, float y)
{
validateElement(ElementUsage.POS, 2);
buffer.put(x + offset.getX());
buffer.put(y + offset.getY());
nextElement();
return this;
}
@Override
public Tesselator pos(float x, float y, float z)
{
validateElement(ElementUsage.POS, 3);
buffer.put(x + offset.getX());
buffer.put(y + offset.getY());
buffer.put(z + offset.getZ());
nextElement();
return this;
}
@Override
public Tesselator color3f(float r, float g, float b)
{
validateElement(ElementUsage.COLOR, 3);
buffer.put(r * effects.getX());
buffer.put(g * effects.getX());
buffer.put(b * effects.getX());
nextElement();
return this;
}
@Override
public Tesselator color4f(float r, float g, float b, float a)
{
validateElement(ElementUsage.COLOR, 4);
buffer.put(r * effects.getX());
buffer.put(g * effects.getX());
buffer.put(b * effects.getX());
buffer.put(a * effects.getY());
nextElement();
return this;
}
@Override
public Tesselator tex(float u, float v)
{
validateElement(ElementUsage.UV, 2);
buffer.put(u);
buffer.put(v);
nextElement();
return this;
}
@Override
public Tesselator normal(float x, float y, float z)
{
validateElement(ElementUsage.NORMAL, 3);
buffer.put(x);
buffer.put(y);
buffer.put(z);
nextElement();
return this;
}
@Override
public Tesselator custom(float x)
{
validateElement(ElementUsage.CUSTOM, 1);
buffer.put(x);
nextElement();
return this;
}
@Override
public Tesselator custom(float x, float y)
{
validateElement(ElementUsage.CUSTOM, 2);
buffer.put(x);
buffer.put(y);
nextElement();
return this;
}
@Override
public Tesselator custom(float x, float y, float z)
{
validateElement(ElementUsage.CUSTOM, 3);
buffer.put(x);
buffer.put(y);
buffer.put(z);
nextElement();
return this;
}
@Override
public Tesselator custom(float x, float y, float z, float w)
{
validateElement(ElementUsage.CUSTOM, 4);
buffer.put(x);
buffer.put(y);
buffer.put(z);
buffer.put(w);
nextElement();
return this;
}
@Override
public Tesselator endVertex()
{
vertexes++;
return this;
}
public Tesselator finishData()
{
drawing = false;
buffer.flip();
return this;
}
public float[] getData()
{
float[] data = new float[currentList.getOffsets() * vertexes];
buffer.get(data);
return data;
}
public DrawCall getDrawCall(int texture)
{
float[] data = new float[currentList.getOffsets() * vertexes];
buffer.get(data);
return new DrawCall(drawType, texture, data, vertexes);
}
public boolean isDrawing()
{
return drawing;
}
public boolean hasTexture()
{
return currentList.hasType(ElementUsage.UV);
}
public int getGLDrawType()
{
return drawType;
}
public void validateElement(ElementUsage usage, int componentSize)
{
if(currentElement.getUsage() == usage && currentElement.getSize() == componentSize && drawing)
{
return;
}
throw new RuntimeException("Invalid Argument, Drawing: "+drawing+", Element: "+usage+", Expected: "+currentElement.getUsage()+", Size: "+componentSize+", Expected Size: "+currentElement.getSize());
}
protected void nextElement()
{
currentIndex = (currentIndex + 1) % currentList.size();
currentElement = currentList.get(currentIndex);
}
public int getVertexCount()
{
return vertexes;
}
}