mirror of
https://github.com/curioustorvald/Terrarum.git
synced 2026-03-07 20:31:51 +09:00
Former-commit-id: 1647fa32ef6894bd7db44f741f07c2f4dcdf9054 Former-commit-id: 0e5810dcfbe1fd59b13e7cabe9f1e93c5542da2d
392 lines
12 KiB
Java
392 lines
12 KiB
Java
package org.newdawn.slick.geom;
|
|
|
|
import org.newdawn.slick.Image;
|
|
import org.newdawn.slick.ShapeFill;
|
|
import org.newdawn.slick.opengl.Texture;
|
|
import org.newdawn.slick.opengl.TextureImpl;
|
|
import org.newdawn.slick.opengl.renderer.LineStripRenderer;
|
|
import org.newdawn.slick.opengl.renderer.Renderer;
|
|
import org.newdawn.slick.opengl.renderer.SGL;
|
|
|
|
/**
|
|
* @author Mark Bernard
|
|
*
|
|
* Use this class to render shpaes directly to OpenGL. Allows you to bypass the Graphics class.
|
|
*/
|
|
public final class ShapeRenderer {
|
|
/** The renderer to use for all GL operations */
|
|
private static SGL GL = Renderer.get();
|
|
/** The renderer to use line strips */
|
|
private static LineStripRenderer LSR = Renderer.getLineStripRenderer();
|
|
|
|
/**
|
|
* Draw the outline of the given shape. Only the vertices are set.
|
|
* The colour has to be set independently of this method.
|
|
*
|
|
* @param shape The shape to draw.
|
|
*/
|
|
public static final void draw(Shape shape) {
|
|
Texture t = TextureImpl.getLastBind();
|
|
TextureImpl.bindNone();
|
|
|
|
float points[] = shape.getPoints();
|
|
|
|
LSR.start();
|
|
for(int i=0;i<points.length;i+=2) {
|
|
LSR.vertex(points[i], points[i + 1]);
|
|
}
|
|
|
|
if (shape.closed()) {
|
|
LSR.vertex(points[0], points[1]);
|
|
}
|
|
|
|
LSR.end();
|
|
|
|
if (t == null) {
|
|
TextureImpl.bindNone();
|
|
} else {
|
|
t.bind();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Draw the outline of the given shape. Only the vertices are set.
|
|
* The colour has to be set independently of this method.
|
|
*
|
|
* @param shape The shape to draw.
|
|
* @param fill The fill to apply
|
|
*/
|
|
public static final void draw(Shape shape, ShapeFill fill) {
|
|
float points[] = shape.getPoints();
|
|
|
|
Texture t = TextureImpl.getLastBind();
|
|
TextureImpl.bindNone();
|
|
|
|
float center[] = shape.getCenter();
|
|
GL.glBegin(SGL.GL_LINE_STRIP);
|
|
for(int i=0;i<points.length;i+=2) {
|
|
fill.colorAt(shape, points[i], points[i + 1]).bind();
|
|
Vector2f offset = fill.getOffsetAt(shape, points[i], points[i + 1]);
|
|
GL.glVertex2f(points[i] + offset.x, points[i + 1] + offset.y);
|
|
}
|
|
|
|
if (shape.closed()) {
|
|
fill.colorAt(shape, points[0], points[1]).bind();
|
|
Vector2f offset = fill.getOffsetAt(shape, points[0], points[1]);
|
|
GL.glVertex2f(points[0] + offset.x, points[1] + offset.y);
|
|
}
|
|
GL.glEnd();
|
|
|
|
if (t == null) {
|
|
TextureImpl.bindNone();
|
|
} else {
|
|
t.bind();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Check there are enough points to fill
|
|
*
|
|
* @param shape THe shape we're drawing
|
|
* @return True if the fill is valid
|
|
*/
|
|
public static boolean validFill(Shape shape) {
|
|
if (shape.getTriangles() == null) {
|
|
return false;
|
|
}
|
|
return shape.getTriangles().getTriangleCount() != 0;
|
|
}
|
|
|
|
/**
|
|
* Draw the the given shape filled in. Only the vertices are set.
|
|
* The colour has to be set independently of this method.
|
|
*
|
|
* @param shape The shape to fill.
|
|
*/
|
|
public static final void fill(Shape shape) {
|
|
if (!validFill(shape)) {
|
|
return;
|
|
}
|
|
|
|
Texture t = TextureImpl.getLastBind();
|
|
TextureImpl.bindNone();
|
|
|
|
fill(shape, new PointCallback() {
|
|
public float[] preRenderPoint(Shape shape, float x, float y) {
|
|
// do nothing, we're just filling the shape this time
|
|
return null;
|
|
}
|
|
});
|
|
|
|
if (t == null) {
|
|
TextureImpl.bindNone();
|
|
} else {
|
|
t.bind();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Draw the the given shape filled in. Only the vertices are set.
|
|
* The colour has to be set independently of this method.
|
|
*
|
|
* @param shape The shape to fill.
|
|
* @param callback The callback that will be invoked for each shape point
|
|
*/
|
|
private static final void fill(Shape shape, PointCallback callback) {
|
|
Triangulator tris = shape.getTriangles();
|
|
|
|
GL.glBegin(SGL.GL_TRIANGLES);
|
|
for (int i=0;i<tris.getTriangleCount();i++) {
|
|
for (int p=0;p<3;p++) {
|
|
float[] pt = tris.getTrianglePoint(i, p);
|
|
float[] np = callback.preRenderPoint(shape, pt[0],pt[1]);
|
|
|
|
if (np == null) {
|
|
GL.glVertex2f(pt[0],pt[1]);
|
|
} else {
|
|
GL.glVertex2f(np[0],np[1]);
|
|
}
|
|
}
|
|
}
|
|
GL.glEnd();
|
|
}
|
|
|
|
/**
|
|
* Draw the the given shape filled in with a texture. Only the vertices are set.
|
|
* The colour has to be set independently of this method.
|
|
*
|
|
* @param shape The shape to texture.
|
|
* @param image The image to tile across the shape
|
|
*/
|
|
public static final void texture(Shape shape, Image image) {
|
|
texture(shape, image, 0.01f, 0.01f);
|
|
}
|
|
|
|
/**
|
|
* Draw the the given shape filled in with a texture. Only the vertices are set.
|
|
* The colour has to be set independently of this method. This method is required to
|
|
* fit the texture once across the shape.
|
|
*
|
|
* @param shape The shape to texture.
|
|
* @param image The image to tile across the shape
|
|
*/
|
|
public static final void textureFit(Shape shape, Image image) {
|
|
textureFit(shape, image,1f,1f);
|
|
}
|
|
|
|
/**
|
|
* Draw the the given shape filled in with a texture. Only the vertices are set.
|
|
* The colour has to be set independently of this method.
|
|
*
|
|
* @param shape The shape to texture.
|
|
* @param image The image to tile across the shape
|
|
* @param scaleX The scale to apply on the x axis for texturing
|
|
* @param scaleY The scale to apply on the y axis for texturing
|
|
*/
|
|
public static final void texture(Shape shape, final Image image, final float scaleX, final float scaleY) {
|
|
if (!validFill(shape)) {
|
|
return;
|
|
}
|
|
|
|
final Texture t = TextureImpl.getLastBind();
|
|
image.getTexture().bind();
|
|
|
|
fill(shape, new PointCallback() {
|
|
public float[] preRenderPoint(Shape shape, float x, float y) {
|
|
float tx = x * scaleX;
|
|
float ty = y * scaleY;
|
|
|
|
tx = image.getTextureOffsetX() + (image.getTextureWidth() * tx);
|
|
ty = image.getTextureOffsetY() + (image.getTextureHeight() * ty);
|
|
|
|
GL.glTexCoord2f(tx, ty);
|
|
return null;
|
|
}
|
|
});
|
|
|
|
float points[] = shape.getPoints();
|
|
|
|
if (t == null) {
|
|
TextureImpl.bindNone();
|
|
} else {
|
|
t.bind();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Draw the the given shape filled in with a texture. Only the vertices are set.
|
|
* The colour has to be set independently of this method. This method is required to
|
|
* fit the texture scaleX times across the shape and scaleY times down the shape.
|
|
*
|
|
* @param shape The shape to texture.
|
|
* @param image The image to tile across the shape
|
|
* @param scaleX The scale to apply on the x axis for texturing
|
|
* @param scaleY The scale to apply on the y axis for texturing
|
|
*/
|
|
public static final void textureFit(Shape shape, final Image image, final float scaleX, final float scaleY) {
|
|
if (!validFill(shape)) {
|
|
return;
|
|
}
|
|
|
|
float points[] = shape.getPoints();
|
|
|
|
Texture t = TextureImpl.getLastBind();
|
|
image.getTexture().bind();
|
|
|
|
final float minX = shape.getX();
|
|
final float minY = shape.getY();
|
|
final float maxX = shape.getMaxX() - minX;
|
|
final float maxY = shape.getMaxY() - minY;
|
|
|
|
fill(shape, new PointCallback() {
|
|
public float[] preRenderPoint(Shape shape, float x, float y) {
|
|
x -= shape.getMinX();
|
|
y -= shape.getMinY();
|
|
|
|
x /= (shape.getMaxX() - shape.getMinX());
|
|
y /= (shape.getMaxY() - shape.getMinY());
|
|
|
|
float tx = x * scaleX;
|
|
float ty = y * scaleY;
|
|
|
|
tx = image.getTextureOffsetX() + (image.getTextureWidth() * tx);
|
|
ty = image.getTextureOffsetY() + (image.getTextureHeight() * ty);
|
|
|
|
GL.glTexCoord2f(tx, ty);
|
|
return null;
|
|
}
|
|
});
|
|
|
|
if (t == null) {
|
|
TextureImpl.bindNone();
|
|
} else {
|
|
t.bind();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Draw the the given shape filled in. Only the vertices are set.
|
|
* The colour has to be set independently of this method.
|
|
*
|
|
* @param shape The shape to fill.
|
|
* @param fill The fill to apply
|
|
*/
|
|
public static final void fill(final Shape shape, final ShapeFill fill) {
|
|
if (!validFill(shape)) {
|
|
return;
|
|
}
|
|
|
|
Texture t = TextureImpl.getLastBind();
|
|
TextureImpl.bindNone();
|
|
|
|
final float center[] = shape.getCenter();
|
|
fill(shape, new PointCallback() {
|
|
public float[] preRenderPoint(Shape shape, float x, float y) {
|
|
fill.colorAt(shape, x, y).bind();
|
|
Vector2f offset = fill.getOffsetAt(shape, x, y);
|
|
|
|
return new float[] {offset.x + x,offset.y + y};
|
|
}
|
|
});
|
|
|
|
if (t == null) {
|
|
TextureImpl.bindNone();
|
|
} else {
|
|
t.bind();
|
|
}
|
|
}
|
|
|
|
|
|
/**
|
|
* Draw the the given shape filled in with a texture. Only the vertices are set.
|
|
* The colour has to be set independently of this method.
|
|
*
|
|
* @param shape The shape to texture.
|
|
* @param image The image to tile across the shape
|
|
* @param scaleX The scale to apply on the x axis for texturing
|
|
* @param scaleY The scale to apply on the y axis for texturing
|
|
* @param fill The fill to apply
|
|
*/
|
|
public static final void texture(final Shape shape, final Image image, final float scaleX, final float scaleY, final ShapeFill fill) {
|
|
if (!validFill(shape)) {
|
|
return;
|
|
}
|
|
|
|
Texture t = TextureImpl.getLastBind();
|
|
image.getTexture().bind();
|
|
|
|
final float center[] = shape.getCenter();
|
|
fill(shape, new PointCallback() {
|
|
public float[] preRenderPoint(Shape shape, float x, float y) {
|
|
fill.colorAt(shape, x - center[0], y - center[1]).bind();
|
|
Vector2f offset = fill.getOffsetAt(shape, x, y);
|
|
|
|
x += offset.x;
|
|
y += offset.y;
|
|
|
|
float tx = x * scaleX;
|
|
float ty = y * scaleY;
|
|
|
|
tx = image.getTextureOffsetX() + (image.getTextureWidth() * tx);
|
|
ty = image.getTextureOffsetY() + (image.getTextureHeight() * ty);
|
|
|
|
GL.glTexCoord2f(tx, ty);
|
|
|
|
return new float[] {offset.x + x,offset.y + y};
|
|
}
|
|
});
|
|
|
|
if (t == null) {
|
|
TextureImpl.bindNone();
|
|
} else {
|
|
t.bind();
|
|
}
|
|
}
|
|
/**
|
|
* Draw the the given shape filled in with a texture. Only the vertices are set.
|
|
* The colour has to be set independently of this method.
|
|
*
|
|
* @param shape The shape to texture.
|
|
* @param image The image to tile across the shape
|
|
* @param gen The texture coordinate generator to create coordiantes for the shape
|
|
*/
|
|
public static final void texture(final Shape shape, Image image, final TexCoordGenerator gen) {
|
|
Texture t = TextureImpl.getLastBind();
|
|
|
|
image.getTexture().bind();
|
|
|
|
final float center[] = shape.getCenter();
|
|
fill(shape, new PointCallback() {
|
|
public float[] preRenderPoint(Shape shape, float x, float y) {
|
|
Vector2f tex = gen.getCoordFor(x, y);
|
|
GL.glTexCoord2f(tex.x, tex.y);
|
|
|
|
return new float[] {x,y};
|
|
}
|
|
});
|
|
|
|
if (t == null) {
|
|
TextureImpl.bindNone();
|
|
} else {
|
|
t.bind();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Description of some feature that will be applied to each point render
|
|
*
|
|
* @author kevin
|
|
*/
|
|
private static interface PointCallback {
|
|
/**
|
|
* Apply feature before the call to glVertex
|
|
*
|
|
* @param shape The shape the point belongs to
|
|
* @param x The x poisiton the vertex will be at
|
|
* @param y The y position the vertex will be at
|
|
* @return The new coordinates of null
|
|
*/
|
|
float[] preRenderPoint(Shape shape, float x, float y);
|
|
}
|
|
}
|