com.voxelplugineering.voxelsniper.render.RenderMain.java Source code

Java tutorial

Introduction

Here is the source code for com.voxelplugineering.voxelsniper.render.RenderMain.java

Source

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014 The Voxel Plugineering Team
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 */
package com.voxelplugineering.voxelsniper.render;

import java.io.File;
import java.nio.FloatBuffer;

import org.lwjgl.BufferUtils;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.ContextAttribs;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL13;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.PixelFormat;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;

import com.voxelplugineering.voxelsniper.Standalone;
import com.voxelplugineering.voxelsniper.entity.Camera;
import com.voxelplugineering.voxelsniper.render.buffer.BufferManager;
import com.voxelplugineering.voxelsniper.render.buffer.sections.TestBufferSection;
import com.voxelplugineering.voxelsniper.util.GLSLUtilities;
import com.voxelplugineering.voxelsniper.util.MathUtilities;
import com.voxelplugineering.voxelsniper.util.OpenGLUtilities;

public class RenderMain {

    private int width;
    private int height;
    private int pId = 0;
    // Moving variables
    private int projectionMatrixLocation = 0;
    private int viewMatrixLocation = 0;
    private int modelMatrixLocation = 0;
    private Matrix4f projectionMatrix = null;
    private Matrix4f viewMatrix = null;
    private Matrix4f modelMatrix = null;
    private FloatBuffer matrix44Buffer = null;

    private BufferManager buffer;
    private TextureManager textures;
    private boolean setup = false;

    public RenderMain(int width, int height) {
        this.width = width;
        this.height = height;
        buffer = new BufferManager();
        textures = new TextureManager();
    }

    public void tick() {
        if (!setup) {
            return;
        }
        Camera camera = Standalone.system().getMainCamera();

        // reset view matrix
        viewMatrix.setIdentity();

        // Translate camera
        Vector3f rot = camera.getCameraRot();
        Matrix4f.rotate(rot.x, new Vector3f(1, 0, 0), viewMatrix, viewMatrix);
        Matrix4f.rotate(rot.y, new Vector3f(0, 1, 0), viewMatrix, viewMatrix);
        Matrix4f.rotate(rot.z, new Vector3f(0, 0, 1), viewMatrix, viewMatrix);
        Matrix4f.translate(camera.getCameraPos(), viewMatrix, viewMatrix);

        GL20.glUseProgram(pId);

        // push matrices
        viewMatrix.store(matrix44Buffer);
        matrix44Buffer.flip();
        GL20.glUniformMatrix4(viewMatrixLocation, false, matrix44Buffer);
        modelMatrix.store(matrix44Buffer);
        matrix44Buffer.flip();
        GL20.glUniformMatrix4(modelMatrixLocation, false, matrix44Buffer);
        projectionMatrix.store(matrix44Buffer);
        matrix44Buffer.flip();
        GL20.glUniformMatrix4(projectionMatrixLocation, false, matrix44Buffer);

        GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);

        // bind textures
        GL13.glActiveTexture(GL13.GL_TEXTURE0);
        GL11.glBindTexture(GL11.GL_TEXTURE_2D, this.textures.get("block"));

        // render all buffer sections
        buffer.renderSections();

        GL20.glUseProgram(0);

        OpenGLUtilities.checkGLError("render main");

        Display.update();
    }

    public void setup() {
        if (Standalone.DEBUG) {
            System.out.println("Starting OGL creation");
        }
        this.setupOpenGL();
        buffer.setup();
        this.setupShaders();
        this.setupTextures();
        this.setupMatrices();
        setup = true;
        buffer.registerBufferSection(new TestBufferSection());
    }

    private void setupTextures() {
        // load all textures
        // debug is first on purpose
        textures.load("debug", new File("assets/textures/debug.png"));
        textures.load("block", new File("assets/textures/block.png"));
    }

    private void setupMatrices() {
        Camera camera = Standalone.system().getMainCamera();
        // Setup projection matrix
        projectionMatrix = new Matrix4f();
        float aspectRatio = (float) this.width / (float) this.height;
        float near_plane = 0.1f;
        float far_plane = 100f;

        float y_scale = MathUtilities.coTangent(MathUtilities.degreesToRadians(camera.getFieldOfView() / 2f));
        float x_scale = y_scale / aspectRatio;
        float frustum_length = far_plane - near_plane;

        projectionMatrix.m00 = x_scale;
        projectionMatrix.m11 = y_scale;
        projectionMatrix.m22 = -((far_plane + near_plane) / frustum_length);
        projectionMatrix.m23 = -1;
        projectionMatrix.m32 = -((2 * near_plane * far_plane) / frustum_length);
        projectionMatrix.m33 = 0;

        // create view as identity matrix
        viewMatrix = new Matrix4f();

        // create model as identity matrix
        modelMatrix = new Matrix4f();

        // Create a FloatBuffer with the proper size to store our matrices later
        matrix44Buffer = BufferUtils.createFloatBuffer(16);
    }

    private void setupOpenGL() {
        // Setup an OpenGL context with API version 3.2
        try {
            PixelFormat pixelFormat = new PixelFormat();
            ContextAttribs contextAtrributes = new ContextAttribs(3, 2).withForwardCompatible(true)
                    .withProfileCore(true);

            Display.setDisplayMode(new DisplayMode(this.width, this.height));
            Display.setTitle("VoxelGunsmithEngine");
            Display.create(pixelFormat, contextAtrributes);
            GL11.glViewport(0, 0, this.width, this.height);
        } catch (LWJGLException e) {
            if (Standalone.DEBUG) {
                System.out.println("Failed creating display");
            }
            e.printStackTrace();
            System.exit(-1);
        }

        // Setup an XNA like background color
        GL11.glClearColor(RenderingConstants.CLEAR_COLOUR_R, RenderingConstants.CLEAR_COLOUR_G,
                RenderingConstants.CLEAR_COLOUR_B, RenderingConstants.CLEAR_COLOUR_A);
        GL11.glViewport(0, 0, this.width, this.height);

        // cull back faces
        GL11.glEnable(GL11.GL_CULL_FACE);
        GL11.glCullFace(GL11.GL_BACK);
        GL11.glFrontFace(GL11.GL_CW);

        OpenGLUtilities.checkGLError("setup OpenGL");
    }

    private void setupShaders() {
        // Load the vertex shader
        int vsId = GLSLUtilities.loadShader("assets/shaders/vertex.glsl", GL20.GL_VERTEX_SHADER);
        // Load the fragment shader
        int fsId = GLSLUtilities.loadShader("assets/shaders/fragment.glsl", GL20.GL_FRAGMENT_SHADER);

        // Create a new shader program that links both shaders
        pId = GL20.glCreateProgram();
        GL20.glAttachShader(pId, vsId);
        GL20.glAttachShader(pId, fsId);

        GL20.glBindAttribLocation(pId, 0, "in_Position");
        GL20.glBindAttribLocation(pId, 1, "in_Color");
        GL20.glBindAttribLocation(pId, 2, "in_TextureCoord");

        GL20.glLinkProgram(pId);
        GL20.glValidateProgram(pId);

        // Get matrices uniform locations
        projectionMatrixLocation = GL20.glGetUniformLocation(pId, "projectionMatrix");
        viewMatrixLocation = GL20.glGetUniformLocation(pId, "viewMatrix");
        modelMatrixLocation = GL20.glGetUniformLocation(pId, "modelMatrix");

        OpenGLUtilities.checkGLError("setupShaders");
    }

    public void destroy() {
        textures.destroy();

        // Delete the shaders
        GL20.glUseProgram(0);
        GL20.glDeleteProgram(pId);

        buffer.destroy();

        OpenGLUtilities.checkGLError("destroyOpenGL");

        Display.destroy();
    }

}