Path: blob/master/SLICK_HOME/src/org/newdawn/slick/geom/ShapeRenderer.java
1461 views
package org.newdawn.slick.geom;12import org.newdawn.slick.Image;3import org.newdawn.slick.ShapeFill;4import org.newdawn.slick.opengl.Texture;5import org.newdawn.slick.opengl.TextureImpl;6import org.newdawn.slick.opengl.renderer.LineStripRenderer;7import org.newdawn.slick.opengl.renderer.Renderer;8import org.newdawn.slick.opengl.renderer.SGL;910/**11* @author Mark Bernard12*13* Use this class to render shpaes directly to OpenGL. Allows you to bypass the Graphics class.14*/15public final class ShapeRenderer {16/** The renderer to use for all GL operations */17private static SGL GL = Renderer.get();18/** The renderer to use line strips */19private static LineStripRenderer LSR = Renderer.getLineStripRenderer();2021/**22* Draw the outline of the given shape. Only the vertices are set.23* The colour has to be set independently of this method.24*25* @param shape The shape to draw.26*/27public static final void draw(Shape shape) {28Texture t = TextureImpl.getLastBind();29TextureImpl.bindNone();3031float points[] = shape.getPoints();3233LSR.start();34for(int i=0;i<points.length;i+=2) {35LSR.vertex(points[i], points[i + 1]);36}3738if (shape.closed()) {39LSR.vertex(points[0], points[1]);40}4142LSR.end();4344if (t == null) {45TextureImpl.bindNone();46} else {47t.bind();48}49}5051/**52* Draw the outline of the given shape. Only the vertices are set.53* The colour has to be set independently of this method.54*55* @param shape The shape to draw.56* @param fill The fill to apply57*/58public static final void draw(Shape shape, ShapeFill fill) {59float points[] = shape.getPoints();6061Texture t = TextureImpl.getLastBind();62TextureImpl.bindNone();6364float center[] = shape.getCenter();65GL.glBegin(SGL.GL_LINE_STRIP);66for(int i=0;i<points.length;i+=2) {67fill.colorAt(shape, points[i], points[i + 1]).bind();68Vector2f offset = fill.getOffsetAt(shape, points[i], points[i + 1]);69GL.glVertex2f(points[i] + offset.x, points[i + 1] + offset.y);70}7172if (shape.closed()) {73fill.colorAt(shape, points[0], points[1]).bind();74Vector2f offset = fill.getOffsetAt(shape, points[0], points[1]);75GL.glVertex2f(points[0] + offset.x, points[1] + offset.y);76}77GL.glEnd();7879if (t == null) {80TextureImpl.bindNone();81} else {82t.bind();83}84}8586/**87* Check there are enough points to fill88*89* @param shape THe shape we're drawing90* @return True if the fill is valid91*/92public static boolean validFill(Shape shape) {93if (shape.getTriangles() == null) {94return false;95}96return shape.getTriangles().getTriangleCount() != 0;97}9899/**100* Draw the the given shape filled in. Only the vertices are set.101* The colour has to be set independently of this method.102*103* @param shape The shape to fill.104*/105public static final void fill(Shape shape) {106if (!validFill(shape)) {107return;108}109110Texture t = TextureImpl.getLastBind();111TextureImpl.bindNone();112113fill(shape, new PointCallback() {114public float[] preRenderPoint(Shape shape, float x, float y) {115// do nothing, we're just filling the shape this time116return null;117}118});119120if (t == null) {121TextureImpl.bindNone();122} else {123t.bind();124}125}126127/**128* Draw the the given shape filled in. Only the vertices are set.129* The colour has to be set independently of this method.130*131* @param shape The shape to fill.132* @param callback The callback that will be invoked for each shape point133*/134private static final void fill(Shape shape, PointCallback callback) {135Triangulator tris = shape.getTriangles();136137GL.glBegin(SGL.GL_TRIANGLES);138for (int i=0;i<tris.getTriangleCount();i++) {139for (int p=0;p<3;p++) {140float[] pt = tris.getTrianglePoint(i, p);141float[] np = callback.preRenderPoint(shape, pt[0],pt[1]);142143if (np == null) {144GL.glVertex2f(pt[0],pt[1]);145} else {146GL.glVertex2f(np[0],np[1]);147}148}149}150GL.glEnd();151}152153/**154* Draw the the given shape filled in with a texture. Only the vertices are set.155* The colour has to be set independently of this method.156*157* @param shape The shape to texture.158* @param image The image to tile across the shape159*/160public static final void texture(Shape shape, Image image) {161texture(shape, image, 0.01f, 0.01f);162}163164/**165* Draw the the given shape filled in with a texture. Only the vertices are set.166* The colour has to be set independently of this method. This method is required to167* fit the texture once across the shape.168*169* @param shape The shape to texture.170* @param image The image to tile across the shape171*/172public static final void textureFit(Shape shape, Image image) {173textureFit(shape, image,1f,1f);174}175176/**177* Draw the the given shape filled in with a texture. Only the vertices are set.178* The colour has to be set independently of this method.179*180* @param shape The shape to texture.181* @param image The image to tile across the shape182* @param scaleX The scale to apply on the x axis for texturing183* @param scaleY The scale to apply on the y axis for texturing184*/185public static final void texture(Shape shape, final Image image, final float scaleX, final float scaleY) {186if (!validFill(shape)) {187return;188}189190final Texture t = TextureImpl.getLastBind();191image.getTexture().bind();192193fill(shape, new PointCallback() {194public float[] preRenderPoint(Shape shape, float x, float y) {195float tx = x * scaleX;196float ty = y * scaleY;197198tx = image.getTextureOffsetX() + (image.getTextureWidth() * tx);199ty = image.getTextureOffsetY() + (image.getTextureHeight() * ty);200201GL.glTexCoord2f(tx, ty);202return null;203}204});205206float points[] = shape.getPoints();207208if (t == null) {209TextureImpl.bindNone();210} else {211t.bind();212}213}214215/**216* Draw the the given shape filled in with a texture. Only the vertices are set.217* The colour has to be set independently of this method. This method is required to218* fit the texture scaleX times across the shape and scaleY times down the shape.219*220* @param shape The shape to texture.221* @param image The image to tile across the shape222* @param scaleX The scale to apply on the x axis for texturing223* @param scaleY The scale to apply on the y axis for texturing224*/225public static final void textureFit(Shape shape, final Image image, final float scaleX, final float scaleY) {226if (!validFill(shape)) {227return;228}229230float points[] = shape.getPoints();231232Texture t = TextureImpl.getLastBind();233image.getTexture().bind();234235final float minX = shape.getX();236final float minY = shape.getY();237final float maxX = shape.getMaxX() - minX;238final float maxY = shape.getMaxY() - minY;239240fill(shape, new PointCallback() {241public float[] preRenderPoint(Shape shape, float x, float y) {242x -= shape.getMinX();243y -= shape.getMinY();244245x /= (shape.getMaxX() - shape.getMinX());246y /= (shape.getMaxY() - shape.getMinY());247248float tx = x * scaleX;249float ty = y * scaleY;250251tx = image.getTextureOffsetX() + (image.getTextureWidth() * tx);252ty = image.getTextureOffsetY() + (image.getTextureHeight() * ty);253254GL.glTexCoord2f(tx, ty);255return null;256}257});258259if (t == null) {260TextureImpl.bindNone();261} else {262t.bind();263}264}265266/**267* Draw the the given shape filled in. Only the vertices are set.268* The colour has to be set independently of this method.269*270* @param shape The shape to fill.271* @param fill The fill to apply272*/273public static final void fill(final Shape shape, final ShapeFill fill) {274if (!validFill(shape)) {275return;276}277278Texture t = TextureImpl.getLastBind();279TextureImpl.bindNone();280281final float center[] = shape.getCenter();282fill(shape, new PointCallback() {283public float[] preRenderPoint(Shape shape, float x, float y) {284fill.colorAt(shape, x, y).bind();285Vector2f offset = fill.getOffsetAt(shape, x, y);286287return new float[] {offset.x + x,offset.y + y};288}289});290291if (t == null) {292TextureImpl.bindNone();293} else {294t.bind();295}296}297298299/**300* Draw the the given shape filled in with a texture. Only the vertices are set.301* The colour has to be set independently of this method.302*303* @param shape The shape to texture.304* @param image The image to tile across the shape305* @param scaleX The scale to apply on the x axis for texturing306* @param scaleY The scale to apply on the y axis for texturing307* @param fill The fill to apply308*/309public static final void texture(final Shape shape, final Image image, final float scaleX, final float scaleY, final ShapeFill fill) {310if (!validFill(shape)) {311return;312}313314Texture t = TextureImpl.getLastBind();315image.getTexture().bind();316317final float center[] = shape.getCenter();318fill(shape, new PointCallback() {319public float[] preRenderPoint(Shape shape, float x, float y) {320fill.colorAt(shape, x - center[0], y - center[1]).bind();321Vector2f offset = fill.getOffsetAt(shape, x, y);322323x += offset.x;324y += offset.y;325326float tx = x * scaleX;327float ty = y * scaleY;328329tx = image.getTextureOffsetX() + (image.getTextureWidth() * tx);330ty = image.getTextureOffsetY() + (image.getTextureHeight() * ty);331332GL.glTexCoord2f(tx, ty);333334return new float[] {offset.x + x,offset.y + y};335}336});337338if (t == null) {339TextureImpl.bindNone();340} else {341t.bind();342}343}344/**345* Draw the the given shape filled in with a texture. Only the vertices are set.346* The colour has to be set independently of this method.347*348* @param shape The shape to texture.349* @param image The image to tile across the shape350* @param gen The texture coordinate generator to create coordiantes for the shape351*/352public static final void texture(final Shape shape, Image image, final TexCoordGenerator gen) {353Texture t = TextureImpl.getLastBind();354355image.getTexture().bind();356357final float center[] = shape.getCenter();358fill(shape, new PointCallback() {359public float[] preRenderPoint(Shape shape, float x, float y) {360Vector2f tex = gen.getCoordFor(x, y);361GL.glTexCoord2f(tex.x, tex.y);362363return new float[] {x,y};364}365});366367if (t == null) {368TextureImpl.bindNone();369} else {370t.bind();371}372}373374/**375* Description of some feature that will be applied to each point render376*377* @author kevin378*/379private static interface PointCallback {380/**381* Apply feature before the call to glVertex382*383* @param shape The shape the point belongs to384* @param x The x poisiton the vertex will be at385* @param y The y position the vertex will be at386* @return The new coordinates of null387*/388float[] preRenderPoint(Shape shape, float x, float y);389}390}391392393