Java tutorial
/* * 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(); } }