io.root.gfx.ModernGraphics.java Source code

Java tutorial

Introduction

Here is the source code for io.root.gfx.ModernGraphics.java

Source

/*******************************************************************************
 * Copyright 2014 Felix Angell freefouran@gmail.com
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *   http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 ******************************************************************************/

package io.root.gfx;

import org.lwjgl.opengl.GL11;

import io.root.font.Glyph;
import io.root.font.TrueTypeFont;
import io.root.gfx.sprites.Sprite;

public class ModernGraphics implements Graphics {

    /** default font, set to anonymous pro -- i like monospaced fonts */
    private TrueTypeFont font = TrueTypeFont.ANONYMOUS_PRO;

    /** sprite batch for rendering sprites */
    private SpriteBatch spriteBatch = new SpriteBatch();

    /** shape batch for rendering shapes */
    private ShapeBatch shapeBatch = new ShapeBatch();

    /** default color if none specified */
    private Color activeColor = Color.WHITE;

    /**
     * Create a new ModernGraphics instance
     * @param spriteBatchSize size of sprite batch
     * @param shapeBatchSize size of shape batch
     */
    public ModernGraphics(int spriteBatchSize, int shapeBatchSize) {
        this.spriteBatch = new SpriteBatch(spriteBatchSize);
        this.shapeBatch = new ShapeBatch(shapeBatchSize);
    }

    @Override
    public void renderSprite(Sprite sprite, float x, float y) {
        renderSprite(sprite, x, y, sprite.getWidth(), sprite.getHeight());
    }

    @Override
    public void renderSprite(Sprite sprite, float x, float y, float w, float h) {
        spriteBatch.render(sprite, x, y, w, h);
    }

    @Override
    public void renderSprite(Sprite sprite, float[] vertices, int offset) {
        spriteBatch.render(sprite, vertices, offset);
    }

    @Override
    public void fillRect(float x, float y, float w, float h) {
        shapeBatch.checkFlush(8);

        final float r = activeColor.r;
        final float g = activeColor.g;
        final float b = activeColor.b;
        final float a = activeColor.a;

        shapeBatch.vertex(x, y, r, g, b, a);
        shapeBatch.vertex(x + w, y, r, g, b, a);
        shapeBatch.vertex(x + w, y + h, r, g, b, a);

        shapeBatch.vertex(x + w, y + h, r, g, b, a);
        shapeBatch.vertex(x, y + h, r, g, b, a);
        shapeBatch.vertex(x, y, r, g, b, a);
    }

    @Override
    public void fillEllipse(float x, float y, float width, float height, int num_of_segments) {
        if (num_of_segments <= 0)
            throw new IllegalArgumentException("num_of_segments must be greater than 0");
        shapeBatch.checkFlush(num_of_segments * 3);

        final float r = activeColor.r;
        final float g = activeColor.g;
        final float b = activeColor.b;
        final float a = activeColor.a;

        float angle = (float) (2 * Math.PI / num_of_segments);
        float cx = x + width / 2;
        float cy = y + height / 2;

        for (int i = 0; i < num_of_segments; i++) {
            shapeBatch.vertex(cx + (width * 0.5f * (float) (Math.cos(i * angle))),
                    cy + (height * 0.5f * (float) (Math.sin(i * angle))), r, g, b, a);
            shapeBatch.vertex(cx, cy, r, g, b, a);
            shapeBatch.vertex(cx + (width * 0.5f * (float) (Math.cos((i + 1) * angle))),
                    cy + (height * 0.5f * (float) (Math.sin((i + 1) * angle))), r, g, b, a);
        }
    }

    @Override
    public void fillTriangle(float x1, float y1, float x2, float y2, float x3, float y3) {
        shapeBatch.checkFlush(6);

        final float r = activeColor.r;
        final float g = activeColor.g;
        final float b = activeColor.b;
        final float a = activeColor.a;

        shapeBatch.vertex(x1, y1, r, g, b, a);
        shapeBatch.vertex(x2, y2, r, g, b, a);
        shapeBatch.vertex(x3, y3, r, g, b, a);
    }

    @Override
    public void fillCircle(float x, float y, float radius, int num_of_segments) {
        if (num_of_segments <= 0)
            throw new IllegalArgumentException("num_of_segments must be greater than 0");

        final float r = activeColor.r;
        final float g = activeColor.g;
        final float b = activeColor.b;
        final float a = activeColor.a;

        final float angle = (float) (2 * Math.PI / num_of_segments);
        final float cos = (float) Math.cos(angle);
        final float sin = (float) Math.sin(angle);
        float cx = radius;
        float cy = 0;

        shapeBatch.checkFlush(num_of_segments * 3 + 3);
        num_of_segments--;

        for (int i = 0; i < num_of_segments; i++) {
            shapeBatch.vertex(x, y, r, g, b, a);
            shapeBatch.vertex(x + cx, y + cy, r, g, b, a);
            float temp = cx;
            cx = cos * cx - sin * cy;
            cy = sin * temp + cos * cy;
            shapeBatch.vertex(x + cx, y + cy, r, g, b, a);
        }

        shapeBatch.vertex(x, y, r, g, b, a);
        shapeBatch.vertex(x + cx, y + cy, r, g, b, a);
    }

    @Override
    public void setColor(float r, float g, float b) {
        setColor(r, g, b, 255f);
    }

    @Override
    public void setColor(float r, float g, float b, float a) {
        activeColor.r = r / 255;
        activeColor.g = g / 255;
        activeColor.b = b / 255;
        activeColor.a = a / 255;
    }

    @Override
    public void renderString(String str, float x, float y) {
        Glyph g = null;
        int totalwidth = 0;
        int totalheight = 0;

        for (int i = 0; i < str.length(); i++) {
            char c = str.charAt(i);
            if (c < 256) {
                g = font.glyphs[c];
            }
            if (g != null) {
                if ((i >= 0) || (i < str.length() - 1)) {
                    spriteBatch.renderSubSprite(font.getFontTexture(), g.x, g.y, g.w, g.h, (x + totalwidth),
                            (y + totalheight), g.w, g.h);
                }
                totalwidth += g.w;
            }
        }
    }

    @Override
    public void setFont(TrueTypeFont font) {
        this.font = font;
    }

    @Override
    public void dispose() {
        spriteBatch.dispose();
        shapeBatch.dispose();
    }

    @Override
    public void beginSpriteBatch() {
        spriteBatch.begin();
    }

    @Override
    public void beginShapeBatch() {
        shapeBatch.begin();
    }

    @Override
    public void endSpriteBatch() {
        spriteBatch.end();
    }

    @Override
    public void endShapeBatch() {
        shapeBatch.end();
    }

    @Override
    public SpriteBatch getSpriteBatch() {
        return spriteBatch;
    }

    @Override
    public ShapeBatch getShapeBatch() {
        return shapeBatch;
    }

    @Override
    public TrueTypeFont getFont() {
        return font;
    }

    @Override
    public void showWireFrame(boolean show) {
        GL11.glPolygonMode(GL11.GL_FRONT_AND_BACK, show ? GL11.GL_LINE : GL11.GL_FILL);
    }

    @Override
    public void setColor(int hex) {
        int r = (hex & 0x00FF0000) >> 16;
        int g = (hex & 0x0000FF00) >> 8;
        int b = (hex & 0x000000FF);
        int a = (hex & 0xFF000000) >> 24;
        if (a < 0)
            a += 256;
        if (a == 0)
            a = 255;
        setColor(r, g, b, a);
    }

}