com.opengrave.og.base.RenderableParticles.java Source code

Java tutorial

Introduction

Here is the source code for com.opengrave.og.base.RenderableParticles.java

Source

/*
 * Copyright 2016 Nathan Howard
 * 
 * This file is part of OpenGrave
 * 
 * OpenGrave is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 * 
 * OpenGrave 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 General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with OpenGrave. If not, see <http://www.gnu.org/licenses/>.
 */
package com.opengrave.og.base;

import java.nio.FloatBuffer;
import java.util.ArrayList;

import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.*;

import com.opengrave.og.MainThread;
import com.opengrave.og.Util;
import com.opengrave.og.engine.ParticlePart;
import com.opengrave.og.light.Shadow;
import com.opengrave.og.resources.RenderStyle;
import com.opengrave.og.resources.Resources;
import com.opengrave.og.util.Matrix4f;
import com.opengrave.og.util.Vector3f;
import com.opengrave.og.util.Vector4f;

public class RenderableParticles extends Renderable3D {

    private ArrayList<ParticlePart> particleList;
    int idVao, idVboPositions, idVboColours, idVboScale, size;

    FloatBuffer positions;
    FloatBuffer colours;
    FloatBuffer scales;

    @Override
    public void render(Matrix4f matrix, RenderStyle style) {
        dealWithChange();
        if (matList == null || !matList.valid()) {
            return;
        }
        GL30.glBindVertexArray(idVao);
        int pID = Resources.loadShader("particle.vs", "particle.fs").getProgram();
        GL20.glUseProgram(pID);
        GL20.glEnableVertexAttribArray(0);
        GL20.glEnableVertexAttribArray(1);
        GL20.glEnableVertexAttribArray(2);
        GL20.glBindAttribLocation(pID, 0, "in_Position");
        GL20.glBindAttribLocation(pID, 1, "in_Colour");
        GL20.glBindAttribLocation(pID, 2, "in_Scale");
        Util.checkErr();
        int texture = GL20.glGetUniformLocation(pID, "tex");
        GL20.glUniform1i(texture, 0);
        int wSS = GL20.glGetUniformLocation(pID, "windowSizeScale");

        GL20.glUniform1f(wSS, getContext().width / 1024f);
        getContext().setMatrices(pID, matrix);
        if (matList != null && matList.valid()) {
            matList.bind(pID, GL13.GL_TEXTURE0);
        }
        GL11.glEnable(GL20.GL_POINT_SPRITE);
        GL11.glEnable(GL20.GL_VERTEX_PROGRAM_POINT_SIZE);
        GL11.glDepthMask(false);
        GL11.glDrawArrays(GL11.GL_POINTS, 0, size);
        GL11.glDepthMask(true);
        GL11.glDisable(GL20.GL_POINT_SPRITE);
        GL11.glDisable(GL20.GL_VERTEX_PROGRAM_POINT_SIZE);

        if (matList != null && matList.valid()) {
            matList.unbind();
        }
        Util.checkErr();

        GL20.glDisableVertexAttribArray(0);
        GL20.glDisableVertexAttribArray(1);
        GL20.glDisableVertexAttribArray(2);

        Util.checkErr();

        GL20.glUseProgram(0);
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
        GL30.glBindVertexArray(0);
        Util.checkErr();
    }

    @Override
    public void renderForPicking(Matrix4f matrix, Pickable object) {
        dealWithChange();
        GL30.glBindVertexArray(idVao);
        int pID = Resources.loadShader("particle.vs", "pickingmodel.fs").getProgram();
        GL20.glUseProgram(pID);
        GL20.glEnableVertexAttribArray(0);
        GL20.glEnableVertexAttribArray(2);
        GL20.glBindAttribLocation(pID, 0, "in_Position");
        GL20.glBindAttribLocation(pID, 2, "in_Scale");
        Util.checkErr();

        int wSS = GL20.glGetUniformLocation(pID, "windowSizeScale");

        GL20.glUniform1f(wSS, MainThread.lastW / 1024f);
        getContext().setMatrices(pID, matrix);
        GL11.glEnable(GL20.GL_POINT_SPRITE);
        GL11.glEnable(GL20.GL_VERTEX_PROGRAM_POINT_SIZE);
        Picking.registerObject(pID, getContext(), object);
        GL11.glDrawArrays(GL11.GL_POINTS, 0, size);
        GL11.glDisable(GL20.GL_POINT_SPRITE);
        GL11.glDisable(GL20.GL_VERTEX_PROGRAM_POINT_SIZE);

        Util.checkErr();

        GL20.glDisableVertexAttribArray(0);
        GL20.glDisableVertexAttribArray(2);

        Util.checkErr();

        GL20.glUseProgram(0);
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
        GL30.glBindVertexArray(0);
        Util.checkErr();
    }

    @Override
    public void renderShadows(Matrix4f matrix, Shadow shadow) {
    }

    @Override
    public void dealWithChange() {
        // Safely assume every frame is a new frame in terms of particle
        // positions.
        if (idVao == 0) {
            idVao = GL30.glGenVertexArrays();
        }
        GL30.glBindVertexArray(idVao);
        if (idVboColours == 0) {
            idVboColours = GL15.glGenBuffers();
        }
        if (idVboPositions == 0) {
            idVboPositions = GL15.glGenBuffers();
        }
        if (idVboScale == 0) {
            idVboScale = GL15.glGenBuffers();
        }

        size = particleList.size() * 4;
        if (positions == null || positions.capacity() != size) {
            positions = BufferUtils.createFloatBuffer(size);
        }
        if (colours == null || colours.capacity() != size) {
            colours = BufferUtils.createFloatBuffer(size);
        }
        if (scales == null || scales.capacity() != size) {
            scales = BufferUtils.createFloatBuffer(size);
        }
        positions.rewind();
        colours.rewind();
        scales.rewind();
        for (ParticlePart particle : particleList) {
            Vector3f pos = particle.getPosition().toVector3(), sca = particle.getScaleData();
            Vector4f col = particle.getColour();

            positions.put(pos.x).put(pos.y).put(pos.z).put(1f);
            colours.put(col.x).put(col.y).put(col.z).put(col.w);
            scales.put(sca.x).put(sca.y).put(sca.z).put(1f);

        }
        positions.flip();
        colours.flip();
        scales.flip();
        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, idVboPositions);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, positions, GL15.GL_STREAM_DRAW);
        GL20.glVertexAttribPointer(0, 4, GL11.GL_FLOAT, false, 0, 0);

        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, idVboColours);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, colours, GL15.GL_STREAM_DRAW);
        GL20.glVertexAttribPointer(1, 4, GL11.GL_FLOAT, false, 0, 0);

        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, idVboScale);
        GL15.glBufferData(GL15.GL_ARRAY_BUFFER, scales, GL15.GL_STREAM_DRAW);
        GL20.glVertexAttribPointer(2, 4, GL11.GL_FLOAT, false, 0, 0);

        GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
        GL30.glBindVertexArray(0);

    }

    @Override
    public void recreate() {
    }

    @Override
    public void addVertex(VertexData vd) {
    }

    @Override
    public void update(float delta) {
    }

    @Override
    public void delete() {
    }

    public void setParticleData(ArrayList<ParticlePart> parts) {
        this.particleList = parts;
    }

}