tectonicus.rasteriser.lwjgl.LwjglMesh.java Source code

Java tutorial

Introduction

Here is the source code for tectonicus.rasteriser.lwjgl.LwjglMesh.java

Source

/*
 * Source code from Tectonicus, http://code.google.com/p/tectonicus/
 *
 * Tectonicus is released under the BSD license (below).
 *
 *
 * Original code John Campbell / "Orangy Tang" / www.triangularpixels.com
 *
 * Copyright (c) 2012, John Campbell
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification,
 * are permitted provided that the following conditions are met:
 *
 *   * Redistributions of source code must retain the above copyright notice, this list
 *     of conditions and the following disclaimer.
 *
 *   * Redistributions in binary form must reproduce the above copyright notice, this
 *     list of conditions and the following disclaimer in the documentation and/or
 *     other materials provided with the distribution.
 *   * Neither the name of 'Tecctonicus' nor the names of
 *     its contributors may be used to endorse or promote products derived
 *    from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
 * OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 */
package tectonicus.rasteriser.lwjgl;

import java.nio.ByteBuffer;
import java.nio.FloatBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.util.vector.Vector3f;
import org.lwjgl.util.vector.Vector4f;

import tectonicus.rasteriser.Mesh;
import tectonicus.rasteriser.Texture;

public class LwjglMesh implements Mesh {
    private LwjglTexture texture;

    private FloatBuffer vertices;
    private ByteBuffer colours;
    private FloatBuffer texCoords;

    private int numVertices;
    private int maxVertices;

    private boolean hasDisplayList;
    private int displayList;

    private boolean isFinalised;

    public LwjglMesh(LwjglTexture texture) {
        this.texture = texture;
    }

    @Override
    public void destroy() {
        if (hasDisplayList) {
            GL11.glDeleteLists(displayList, 1);
            displayList = 0;
            hasDisplayList = false;
        }
    }

    @Override
    public void addVertex(Vector3f position, Vector4f colour, final float u, final float v) {
        assert (!isFinalised);

        if (numVertices + 3 > maxVertices) {
            final int newMax = maxVertices + 2000;

            vertices = realloc(vertices, maxVertices * 3, newMax * 3);
            colours = realloc(colours, maxVertices * 4, newMax * 4);
            texCoords = realloc(texCoords, maxVertices * 2, newMax * 2);

            maxVertices = newMax;
        }

        vertices.put(position.x);
        vertices.put(position.y);
        vertices.put(position.z);

        colours.put((byte) (colour.x * 255));
        colours.put((byte) (colour.y * 255));
        colours.put((byte) (colour.z * 255));
        colours.put((byte) (colour.w * 255));

        texCoords.put(u);
        texCoords.put(v);

        numVertices++;
        assert (numVertices < maxVertices);
    }

    @Override
    public void addVertex(Vector3f position, final float u, final float v) {
        assert (!isFinalised);

        vertices.put(position.x);
        vertices.put(position.y);
        vertices.put(position.z);

        colours.put((byte) 255);
        colours.put((byte) 255);
        colours.put((byte) 255);
        colours.put((byte) 255);

        texCoords.put(u);
        texCoords.put(v);

        numVertices++;
        assert (numVertices < maxVertices);
    }

    @Override
    public void finalise() {
        assert (!isFinalised);

        if (vertices != null)
            vertices.flip();

        if (colours != null)
            colours.flip();

        if (texCoords != null)
            texCoords.flip();

        isFinalised = true;
    }

    @Override
    public Texture getTexture() {
        return texture;
    }

    @Override
    public void bind() {
        if (vertices == null)
            return;

        assert (isFinalised);
        assert (numVertices > 0);

        org.lwjgl.opengl.Util.checkGLError();

        GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
        GL11.glVertexPointer(3, 0, vertices);

        GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
        GL11.glColorPointer(4, true, 0, colours);

        GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
        GL11.glTexCoordPointer(2, 0, texCoords);

        if (texture != null) {
            GL11.glEnable(GL11.GL_TEXTURE_2D);
            GL11.glBindTexture(GL11.GL_TEXTURE_2D, texture.getId());
        } else {
            GL11.glDisable(GL11.GL_TEXTURE_2D);
            GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0);
        }

        org.lwjgl.opengl.Util.checkGLError();
    }

    @Override
    public void draw(final float xOffset, final float yOffset, final float zOffset) {
        if (vertices == null)
            return;

        assert (numVertices > 0);

        //   if (hasDisplayList)
        {
            //      GL11.glCallList(displayList);
        }
        //   else
        {
            //      org.lwjgl.opengl.Util.checkGLError();

            //   displayList = GL11.glGenLists(1);

            //   GL11.glNewList(displayList, GL11.GL_COMPILE);
            {
                GL11.glPushMatrix();
                GL11.glTranslatef(xOffset, yOffset, zOffset);

                GL11.glDrawArrays(GL11.GL_QUADS, 0, numVertices);

                GL11.glPopMatrix();
            }
            //   GL11.glEndList();

            //   GL11.glCallList(displayList);

            //   hasDisplayList = true;

            //   org.lwjgl.opengl.Util.checkGLError();
        }
    }

    @Override
    public int getMemorySize() {
        if (vertices == null)
            return 0;

        final int vertexMem = vertices.capacity() * 4;
        final int coloursMem = colours.capacity();
        final int texCoordMem = texCoords.capacity() * 4;

        return vertexMem + coloursMem + texCoordMem;
    }

    @Override
    public int getTotalVertices() {
        return numVertices;
    }

    private static FloatBuffer realloc(FloatBuffer existing, final int existingSize, final int newSize) {
        FloatBuffer newBuffer = BufferUtils.createFloatBuffer(newSize);

        if (existing != null) {
            existing.flip();
            newBuffer.put(existing);
        }

        return newBuffer;
    }

    private static ByteBuffer realloc(ByteBuffer existing, final int existingSize, final int newSize) {
        ByteBuffer newBuffer = BufferUtils.createByteBuffer(newSize);

        if (existing != null) {
            existing.flip();
            newBuffer.put(existing);
        }

        return newBuffer;
    }
}