taiga.gpvm.render.ColorTileRenderer.java Source code

Java tutorial

Introduction

Here is the source code for taiga.gpvm.render.ColorTileRenderer.java

Source

/*
 * Copyright (C) 2014 Russell Smith.
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 3.0 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
 * MA 02110-1301  USA
 */

package taiga.gpvm.render;

import taiga.gpvm.util.geom.Coordinate;
import java.nio.ByteBuffer;
import java.nio.IntBuffer;
import java.util.ArrayList;
import java.util.List;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import taiga.code.math.ReadableMatrix4;
import taiga.code.opengl.shaders.ShaderProgram;
import taiga.gpvm.HardcodedValues;
import taiga.gpvm.map.Tile;
import taiga.gpvm.opengl.ResourceManager;
import taiga.gpvm.registry.RenderingInfo;
import taiga.gpvm.util.geom.Direction;

/**
 *
 * @author russell
 */
public class ColorTileRenderer implements TileRenderer {

    public ColorTileRenderer(RegionRenderer parent) {
        ResourceManager resources = parent.getObject(HardcodedValues.NAME_RESOURCE_MANAGER);
        assert resources != null;

        simplecolor = resources.getResource(ShaderProgram.SHADER_NAME_SIMPLE_COLOR, ShaderProgram.class);
        projloc = simplecolor.getUniformLocation("projection");
        mvloc = simplecolor.getUniformLocation("modelview");
    }

    @Override
    public void compile(List<TileInfo> tiles) {
        ArrayList<Coordinate> vertices = new ArrayList<>();
        ArrayList<Integer> colors = new ArrayList<>();

        for (TileInfo info : tiles) {
            Coordinate corner = info.absposition.getRelativeCoordinate();

            //Magenta is the default color for uglyness.
            int color = 0xFFFF00FF;
            if (info.rendentry != null && info.rendentry.info instanceof ColorInfo) {
                color = ((ColorInfo) info.rendentry.info).color;
            }

            //south face
            Tile adj = info.adjacent[Direction.South.getIndex()];
            if (adj == null || adj.type == null || !adj.type.opaque) {
                vertices.add(corner);
                vertices.add(corner.add(1, 0, 0, new Coordinate()));
                vertices.add(corner.add(1, 0, 1, new Coordinate()));
                vertices.add(corner.add(0, 0, 1, new Coordinate()));
                colors.add(color);
            }

            //north face
            adj = info.adjacent[Direction.North.getIndex()];
            if (adj == null || adj.type == null || !adj.type.opaque) {
                vertices.add(corner.add(0, 1, 0, new Coordinate()));
                vertices.add(corner.add(1, 1, 0, new Coordinate()));
                vertices.add(corner.add(1, 1, 1, new Coordinate()));
                vertices.add(corner.add(0, 1, 1, new Coordinate()));
                colors.add(color);
            }

            //west face
            adj = info.adjacent[Direction.West.getIndex()];
            if (adj == null || adj.type == null || !adj.type.opaque) {
                vertices.add(corner);
                vertices.add(corner.add(0, 1, 0, new Coordinate()));
                vertices.add(corner.add(0, 1, 1, new Coordinate()));
                vertices.add(corner.add(0, 0, 1, new Coordinate()));
                colors.add(color);
            }

            //east face
            adj = info.adjacent[Direction.East.getIndex()];
            if (adj == null || adj.type == null || !adj.type.opaque) {
                vertices.add(corner.add(1, 0, 0, new Coordinate()));
                vertices.add(corner.add(1, 1, 0, new Coordinate()));
                vertices.add(corner.add(1, 1, 1, new Coordinate()));
                vertices.add(corner.add(1, 0, 1, new Coordinate()));
                colors.add(color);
            }

            //bottom face
            adj = info.adjacent[Direction.Down.getIndex()];
            if (adj == null || adj.type == null || !adj.type.opaque) {
                vertices.add(corner);
                vertices.add(corner.add(1, 0, 0, new Coordinate()));
                vertices.add(corner.add(1, 1, 0, new Coordinate()));
                vertices.add(corner.add(0, 1, 0, new Coordinate()));
                colors.add(color);
            }

            //top face
            adj = info.adjacent[Direction.Up.getIndex()];
            if (adj == null || adj.type == null || !adj.type.opaque) {
                vertices.add(corner.add(0, 0, 1, new Coordinate()));
                vertices.add(corner.add(1, 0, 1, new Coordinate()));
                vertices.add(corner.add(1, 1, 1, new Coordinate()));
                vertices.add(corner.add(0, 1, 1, new Coordinate()));
                colors.add(color);
            }
        }

        verts = BufferUtils.createIntBuffer(3 * vertices.size());
        color = BufferUtils.createByteBuffer(48 * colors.size());
        IntBuffer tcolor = color.asIntBuffer();

        for (Coordinate coor : vertices) {
            verts.put(coor.x);
            verts.put(coor.y);
            verts.put(coor.z);
        }

        for (Integer col : colors) {
            tcolor.put(col);
            tcolor.put(col);
            tcolor.put(col);
            tcolor.put(col);
        }

        verts.flip();
        color.flip();
    }

    @Override
    public void render(int pass, ReadableMatrix4 proj, ReadableMatrix4 modelview) {
        if (verts == null || color == null || pass != HardcodedValues.OPAQUE_WORLD_LAYER)
            return;

        simplecolor.bind();

        simplecolor.setUniformMatrix(projloc, proj);
        simplecolor.setUniformMatrix(mvloc, modelview);

        GL11.glPushClientAttrib(GL11.GL_VERTEX_ARRAY | GL11.GL_COLOR_ARRAY);

        GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
        GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);

        GL11.glEnable(GL11.GL_DEPTH_TEST);

        //There are 3 elements to each vertex
        //stride is zero the vertices are tightly packed.
        GL11.glVertexPointer(3, 0, verts);

        //4 elements in each color: alpha, red, green, and blue
        GL11.glColorPointer(4, true, 0, color);

        GL11.glDrawArrays(GL11.GL_QUADS, 0, verts.limit() / 3);

        GL11.glPopClientAttrib();
    }

    public void release() {
        if (simplecolor != null)
            simplecolor.unload();
        color = null;
        verts = null;
    }

    public static final Class<? extends RenderingInfo> INFO_CLASS = ColorInfo.class;

    private ShaderProgram.Location projloc;
    private ShaderProgram.Location mvloc;
    private ShaderProgram simplecolor;
    private ByteBuffer color;
    private IntBuffer verts;
}