/**
   * 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.
   *
   * @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();
    }
  }