/* * To change this license header, choose License Headers in Project Properties. * To change this template file, choose Tools | Templates * and open the template in the editor. */ package electrosphere.renderer; import electrosphere.entity.CameraEntityUtils; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.util.ArrayList; import java.util.Iterator; import electrosphere.main.Globals; import static electrosphere.main.Main.view_Range; import org.joml.Matrix4f; import org.joml.Vector3f; import org.lwjgl.BufferUtils; import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MAJOR; import static org.lwjgl.glfw.GLFW.GLFW_CONTEXT_VERSION_MINOR; import static org.lwjgl.glfw.GLFW.GLFW_CURSOR; import static org.lwjgl.glfw.GLFW.GLFW_CURSOR_DISABLED; import static org.lwjgl.glfw.GLFW.GLFW_FALSE; import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_CORE_PROFILE; import static org.lwjgl.glfw.GLFW.GLFW_OPENGL_PROFILE; import static org.lwjgl.glfw.GLFW.GLFW_TRANSPARENT_FRAMEBUFFER; import static org.lwjgl.glfw.GLFW.GLFW_TRUE; import static org.lwjgl.glfw.GLFW.glfwCreateWindow; import static org.lwjgl.glfw.GLFW.glfwInit; import static org.lwjgl.glfw.GLFW.glfwMakeContextCurrent; import static org.lwjgl.glfw.GLFW.glfwMaximizeWindow; import static org.lwjgl.glfw.GLFW.glfwSetInputMode; import static org.lwjgl.glfw.GLFW.glfwTerminate; import static org.lwjgl.glfw.GLFW.glfwWindowHint; import org.lwjgl.opengl.GL; import org.lwjgl.opengl.GL11; import static org.lwjgl.opengl.GL11.GL_BLEND; import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; import static org.lwjgl.opengl.GL11.GL_FLOAT; import static org.lwjgl.opengl.GL11.GL_INT; import static org.lwjgl.opengl.GL11.GL_LEQUAL; import static org.lwjgl.opengl.GL11.GL_LESS; import static org.lwjgl.opengl.GL11.GL_ONE_MINUS_SRC_ALPHA; import static org.lwjgl.opengl.GL11.GL_SHORT; import static org.lwjgl.opengl.GL11.GL_SRC_ALPHA; import static org.lwjgl.opengl.GL11.GL_TRIANGLES; import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT; import static org.lwjgl.opengl.GL11.glBlendFunc; import static org.lwjgl.opengl.GL11.glEnable; import org.lwjgl.opengl.GL15; import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER; import static org.lwjgl.opengl.GL15.GL_STATIC_DRAW; import static org.lwjgl.opengl.GL15.glBindBuffer; import static org.lwjgl.opengl.GL15.glGenBuffers; import org.lwjgl.opengl.GL20; import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray; import static org.lwjgl.opengl.GL20.glGetUniformLocation; import static org.lwjgl.opengl.GL20.glUniform1fv; import static org.lwjgl.opengl.GL20.glUniform1i; import static org.lwjgl.opengl.GL20.glUniform3fv; import static org.lwjgl.opengl.GL20.glUniformMatrix4fv; import static org.lwjgl.opengl.GL20.glUseProgram; import static org.lwjgl.opengl.GL20.glVertexAttribPointer; import static org.lwjgl.opengl.GL30.glBindVertexArray; import static org.lwjgl.opengl.GL30.glGenVertexArrays; import static org.lwjgl.system.MemoryUtil.NULL; /** * * @author amaterasu */ public class RenderUtils { public static void createOpenglContext(){ //Sets the variables that control the window sizing int screenWidth = 1920; int screenHeight = 1080; //Initializes opengl glfwInit(); //Gives hints to glfw to control how opengl will be used glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3); glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3); glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE); // glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); Allows you to make the background transparent // glfwWindowHint(GLFW_OPACITY, 23); //Creates the window reference object Globals.window = glfwCreateWindow(screenWidth, screenHeight, "LearnOpenGL", NULL, NULL); //Errors for failure to create window (IE: No GUI mode on linux ?) if (Globals.window == NULL) { System.out.println("Failed to make window."); glfwTerminate(); } //Makes the window that was just created the current OS-level window context glfwMakeContextCurrent(Globals.window); //Maximize it glfwMaximizeWindow(Globals.window); //Creates the OpenGL capabilities for the program. GL.createCapabilities(); //This enables Z-buffering so that farther-back polygons are not drawn over nearer ones glEnable(GL_DEPTH_TEST); // Support for transparency glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); //Hide the cursor and capture it glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); //Points the texture uniforms in the shader programs at the correct variables // // Projection and View matrix creation // Globals.projectionMatrix = new Matrix4f(); Globals.viewMatrix = new Matrix4f(); float FOV = (float)(120.0f * Math.PI /180.0f); Globals.projectionMatrix.setPerspective(FOV, 1.0f, 0.1f, view_Range); Globals.viewMatrix.translation(new Vector3f(0.0f,0.0f,-3.0f)); } public static void recaptureScreen(){ //Makes the window that was just created the current OS-level window context glfwMakeContextCurrent(Globals.window); //Maximize it glfwMaximizeWindow(Globals.window); //Hide the cursor and capture it glfwSetInputMode(Globals.window, GLFW_CURSOR, GLFW_CURSOR_DISABLED); } public static Model createSkyboxModel(Material optionalMaterial){ Model skyboxModel = new Model(); skyboxModel.meshes = new ArrayList(); skyboxModel.modelMatrix = new Matrix4f(); boolean apply_lighting = false; boolean has_bones = false; Mesh skyboxmesh = new Mesh(){ @Override public void draw(){ GL11.glDepthFunc(GL_LEQUAL); glUseProgram(shader.shaderProgram); if(material == null){ Globals.materialDefault.apply_material(0,1); Iterator colorIterator = Globals.skyboxColors.iterator(); int counter = 0; float[] temp = new float[3]; while(colorIterator.hasNext()){ Vector3f colorCurrent = colorIterator.next(); temp[0] = colorCurrent.x / 255.0f; temp[1] = colorCurrent.y / 255.0f; temp[2] = colorCurrent.z / 255.0f; // System.out.println("colors[" + counter + "] " + temp[0] + " " + temp[1] + " " + temp[2]); glUniform3fv(glGetUniformLocation(shader.shaderProgram, "colors[" + counter + "]"), temp); counter++; } } glBindVertexArray(vertexArrayObject); //buffer model/view/proj matrices glUniformMatrix4fv(shader.shaderVertexModelLoc, false, parent.modelMatrix.get(new float[16])); glUniformMatrix4fv(shader.shaderVertexViewLoc, false, new Matrix4f(Globals.viewMatrix).scale(100).get(new float[16])); glUniformMatrix4fv(shader.shaderVertexProjectionLoc, false, Globals.projectionMatrix.get(new float[16])); glUniform3fv(shader.shaderVertexViewPosLoc, CameraEntityUtils.getCameraEye(Globals.playerCamera).get(BufferUtils.createFloatBuffer(3))); GL11.glDrawElements(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, 0); glBindVertexArray(0); GL11.glDepthFunc(GL_LESS); } }; skyboxmesh.mesh = null; // // VAO // skyboxmesh.vertexArrayObject = glGenVertexArrays(); glBindVertexArray(skyboxmesh.vertexArrayObject); float[] vertexcoords = { 1.0f,1.0f,1.0f, 1.0f,1.0f,-1.0f, 1.0f,-1.0f,1.0f, 1.0f,-1.0f,-1.0f, -1.0f,1.0f,1.0f, -1.0f,1.0f,-1.0f, -1.0f,-1.0f,1.0f, -1.0f,-1.0f,-1.0f, }; // //Buffer data to GPU // try { skyboxmesh.vertexCount = vertexcoords.length / 3; FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(skyboxmesh.vertexCount * 3); float[] temp = new float[3]; for (int i = 0; i < skyboxmesh.vertexCount; i++) { temp[0] = vertexcoords[i * 3 + 0]; temp[1] = vertexcoords[i * 3 + 1]; temp[2] = vertexcoords[i * 3 + 2]; VertexArrayBufferData.put(temp); } VertexArrayBufferData.flip(); skyboxmesh.buffer_vertices(VertexArrayBufferData); } catch (NullPointerException ex){ ex.printStackTrace(); } int[] facedata = { 0,1,4, 1,4,5, 1,3,5, 3,5,7, 4,5,7, 4,6,7, 0,2,4, 2,4,6, 0,1,2, 1,2,3, 2,3,6, 3,6,7, }; // // FACES // skyboxmesh.faceCount = facedata.length / 3; skyboxmesh.elementCount = facedata.length; IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(skyboxmesh.elementCount); for(int i = 0; i < skyboxmesh.faceCount; i++){ int[] temp = new int[3]; temp[0] = facedata[i * 3 + 0]; temp[1] = facedata[i * 3 + 1]; temp[2] = facedata[i * 3 + 2]; elementArrayBufferData.put(temp); } elementArrayBufferData.flip(); skyboxmesh.buffer_faces(elementArrayBufferData); if(optionalMaterial != null){ // // NORMALS // try { skyboxmesh.normalCount = vertexcoords.length / 3; FloatBuffer NormalArrayBufferData; if(skyboxmesh.normalCount > 0){ NormalArrayBufferData = BufferUtils.createFloatBuffer(skyboxmesh.normalCount * 3); float[] temp = new float[3]; for (int i = 0; i < skyboxmesh.normalCount; i++) { temp[0] = vertexcoords[i * 3 + 0]; temp[1] = vertexcoords[i * 3 + 1]; temp[2] = vertexcoords[i * 3 + 2]; NormalArrayBufferData.put(temp); } NormalArrayBufferData.flip(); skyboxmesh.buffer_normals(NormalArrayBufferData); } } catch (NullPointerException ex){ ex.printStackTrace(); } // // TEXTURE COORDINATES // /*try { skyboxmesh.textureCoordCount = mesh.mTextureCoords(0).capacity(); FloatBuffer TextureArrayBufferData; if(skyboxmesh.textureCoordCount > 0){ TextureArrayBufferData = BufferUtils.createFloatBuffer(skyboxmesh.textureCoordCount * 2); float[] temp = new float[2]; for (int i = 0; i < skyboxmesh.textureCoordCount; i++) { AIVector3D normal = texturecoords.get(i); temp[0] = normal.x(); temp[1] = normal.y(); // temp[2] = normal.z(); TextureArrayBufferData.put(temp); } TextureArrayBufferData.flip(); skyboxmesh.buffer_texture_coords(TextureArrayBufferData); } } catch (NullPointerException ex){ ex.printStackTrace(); } skyboxmesh.shader = ShaderProgram.smart_assemble_shader(has_bones, apply_lighting); skybox_model.materials.add(optionalMaterial); */ } else { skyboxmesh.shader = ShaderProgram.loadSpecificShader("/Shaders/skybox/VertexShaderNoTexture.vs", "/Shaders/skybox/FragmentShaderNoTexture.fs"); try { FloatBuffer ColorArrayBufferData = BufferUtils.createFloatBuffer(skyboxmesh.vertexCount); for (int i = 0; i < skyboxmesh.vertexCount; i++) { ColorArrayBufferData.put(i); } ColorArrayBufferData.flip(); int idBuffer = glGenBuffers(); glBindBuffer(GL_ARRAY_BUFFER, idBuffer); GL15.glBufferData(GL_ARRAY_BUFFER, ColorArrayBufferData, GL_STATIC_DRAW); glVertexAttribPointer(1, 1, GL11.GL_FLOAT, false, 0, 0); glEnableVertexAttribArray(1); } catch (NullPointerException ex){ ex.printStackTrace(); } } skyboxmesh.hasBones = false; glBindVertexArray(0); skyboxmesh.nodeID = "skybox"; skyboxmesh.parent = skyboxModel; skyboxModel.meshes.add(skyboxmesh); return skyboxModel; } }