org.spout.engine.renderer.GLBatchInstanceRenderer.java Source code

Java tutorial

Introduction

Here is the source code for org.spout.engine.renderer.GLBatchInstanceRenderer.java

Source

/*
 * This file is part of Spout.
 *
 * Copyright (c) 2011-2012, Spout LLC <http://www.spout.org/>
 * Spout is licensed under the Spout License Version 1.
 *
 * Spout 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 of the License, or (at your option)
 * any later version.
 *
 * In addition, 180 days after any changes are published, you can use the
 * software, incorporating those changes, under the terms of the MIT license,
 * as described in the Spout License Version 1.
 *
 * Spout 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,
 * the MIT license and the Spout License Version 1 along with this program.
 * If not, see <http://www.gnu.org/licenses/> for the GNU Lesser General Public
 * License and see <http://spout.in/licensev1> for the full license, including
 * the MIT license.
 */
package org.spout.engine.renderer;

import java.nio.Buffer;
import java.nio.FloatBuffer;
import java.util.ArrayList;
import java.util.Map;
import java.util.Map.Entry;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.opengl.GL31;
import org.spout.api.render.RenderMaterial;
import org.spout.engine.SpoutRenderer;
import org.spout.engine.renderer.vertexbuffer.SpoutFloatBuffer;

public class GLBatchInstanceRenderer extends BatchVertexRenderer {
    final int SIZE_FLOAT = 4;
    int vao;
    int vbos = -1;

    ArrayList<Integer> assigned = new ArrayList<Integer>();

    SpoutFloatBuffer buffer = null;
    //TIntObjectHashMap<GLFloatBuffer > vertexBuffers = new TIntObjectHashMap<GLFloatBuffer>();

    /**
     * Batch Renderer using OpenGL 3.0 mode.
     * @param renderMode Mode to render in
     */
    public GLBatchInstanceRenderer(int renderMode) {
        super(renderMode);
        vao = GL30.glGenVertexArrays();
        SpoutRenderer.checkGLError();
        //Util.checkGLError();
        //GL30.glBindVertexArray(vao); // useless
        //vertexBuffers.put(0, new VertexBufferImpl("vPosition", 4, 0)); //Auto create the first time
    }

    @Override
    protected void initFlush(Map<Integer, Buffer> buffers) {
        int size = 0;
        int[] layouts = new int[buffers.size()];
        int[] elements = new int[buffers.size()];
        FloatBuffer[] floatBuffers = new FloatBuffer[buffers.size()];

        int i = 0;
        for (Entry<Integer, Buffer> entry : buffers.entrySet()) {
            layouts[i] = entry.getKey();
            floatBuffers[i] = (FloatBuffer) entry.getValue();
            elements[i] = floatBuffers[i].limit() / flushingNumVertices;
            size += floatBuffers[i].limit();
            i++;
        }

        FloatBuffer buffer = BufferUtils.createFloatBuffer(size);
        buffer.clear();

        for (int vertex = 0; vertex < flushingNumVertices; vertex++) {
            for (i = 0; i < layouts.length; i++) {
                for (int k = 0; k < elements[i]; k++) {
                    buffer.put(floatBuffers[i].get(vertex * elements[i] + k));
                }
            }
        }

        buffer.flip();

        if (flushingBuffer == null)
            flushingBuffer = SpoutFloatBuffer.getBuffer();

        flushingBuffer.setData(elements, layouts, buffer);
    }

    @Override
    protected boolean doFlush(boolean force) {
        if (flushingBuffer.flush(force)) {
            GL30.glBindVertexArray(vao);
            SpoutRenderer.checkGLError();

            if (currentBuffer != null) {
                currentBuffer.unbind();
                for (int layout : currentBuffer.getLayout()) {
                    GL20.glDisableVertexAttribArray(layout);
                    SpoutRenderer.checkGLError();
                }
            }

            flushingBuffer.bind(true);

            for (int layout : flushingBuffer.getLayout()) {
                GL20.glEnableVertexAttribArray(layout);
                SpoutRenderer.checkGLError();
            }

            GL30.glBindVertexArray(0);
            SpoutRenderer.checkGLError();
            return true;
        }
        return false;
    }

    @Override
    public void preDraw() {
        //Nothing to do
    }

    /**
     * Draws this batch
     */
    @Override
    public void doDraw(RenderMaterial material, int elements, int instances) {
        GL30.glBindVertexArray(vao);
        SpoutRenderer.checkGLError();

        material.assign();

        //System.out.println("glDrawArrays");
        // RenderModer, ? , Type of index of instance, ? , ?
        GL31.glDrawArraysInstanced(renderMode, 0, elements, instances);
        SpoutRenderer.checkGLError();

        //GL30.glBindVertexArray(0); //Run without
    }

    @Override
    public void postDraw() {
        //Nothing to do
    }

    @Override
    public void doRelease() {
        if (currentBuffer != null) {
            currentBuffer.release();
            currentBuffer = null;
        }
        if (flushingBuffer != null) {
            flushingBuffer.release();
            flushingBuffer = null;
        }
    }

    public void finalize() {
        if (currentBuffer != null) {
            currentBuffer.release();
            currentBuffer = null;
        }
        if (flushingBuffer != null) {
            flushingBuffer.release();
            flushingBuffer = null;
        }
        GL30.glDeleteVertexArrays(vao);
    }

}