package electrosphere.renderer; import electrosphere.entity.CameraEntityUtils; import electrosphere.entity.Entity; import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; import java.nio.FloatBuffer; import java.nio.IntBuffer; import java.util.ArrayList; import java.util.Iterator; import electrosphere.main.Globals; import electrosphere.main.Main; import static electrosphere.main.Main.deltaTime; import static electrosphere.main.Main.view_Range; import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.framebuffer.FramebufferUtils; import electrosphere.renderer.framebuffer.Renderbuffer; import electrosphere.renderer.ui.Widget; import electrosphere.util.Utilities; import org.joml.Matrix4f; import org.joml.Quaternionf; 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.glfwPollEvents; import static org.lwjgl.glfw.GLFW.glfwSetInputMode; import static org.lwjgl.glfw.GLFW.glfwSwapBuffers; 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_BACK; import static org.lwjgl.opengl.GL11.GL_BLEND; import static org.lwjgl.opengl.GL11.GL_COLOR_BUFFER_BIT; import static org.lwjgl.opengl.GL11.GL_CULL_FACE; import static org.lwjgl.opengl.GL11.GL_DEPTH_BUFFER_BIT; import static org.lwjgl.opengl.GL11.GL_DEPTH_TEST; import static org.lwjgl.opengl.GL11.GL_FLOAT; import static org.lwjgl.opengl.GL11.GL_FRONT; 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_TEXTURE_2D; import static org.lwjgl.opengl.GL11.GL_TRIANGLES; import static org.lwjgl.opengl.GL11.GL_TRUE; import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT; import static org.lwjgl.opengl.GL11.glBindTexture; import static org.lwjgl.opengl.GL11.glBlendFunc; import static org.lwjgl.opengl.GL11.glClear; import static org.lwjgl.opengl.GL11.glClearColor; import static org.lwjgl.opengl.GL11.glCullFace; import static org.lwjgl.opengl.GL11.glDisable; import static org.lwjgl.opengl.GL11.glDrawArrays; import static org.lwjgl.opengl.GL11.glEnable; import static org.lwjgl.opengl.GL11.glViewport; import static org.lwjgl.opengl.GL13.GL_TEXTURE0; import static org.lwjgl.opengl.GL13.GL_TEXTURE1; import static org.lwjgl.opengl.GL13.GL_TEXTURE2; import static org.lwjgl.opengl.GL13.GL_TEXTURE3; import static org.lwjgl.opengl.GL13.glActiveTexture; 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.GL_COMPILE_STATUS; import static org.lwjgl.opengl.GL20.GL_FRAGMENT_SHADER; import static org.lwjgl.opengl.GL20.GL_LINK_STATUS; import static org.lwjgl.opengl.GL20.GL_VERTEX_SHADER; import static org.lwjgl.opengl.GL20.glAttachShader; import static org.lwjgl.opengl.GL20.glCompileShader; import static org.lwjgl.opengl.GL20.glCreateProgram; import static org.lwjgl.opengl.GL20.glCreateShader; import static org.lwjgl.opengl.GL20.glDeleteShader; import static org.lwjgl.opengl.GL20.glEnableVertexAttribArray; import static org.lwjgl.opengl.GL20.glGetProgramInfoLog; import static org.lwjgl.opengl.GL20.glGetProgrami; import static org.lwjgl.opengl.GL20.glGetShaderi; import static org.lwjgl.opengl.GL20.glGetUniformLocation; import static org.lwjgl.opengl.GL20.glLinkProgram; import static org.lwjgl.opengl.GL20.glShaderSource; 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.GL_FRAMEBUFFER; import static org.lwjgl.opengl.GL30.GL_RENDERBUFFER; import static org.lwjgl.opengl.GL30.glBindFramebuffer; import static org.lwjgl.opengl.GL30.glBindRenderbuffer; 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 { static int createScreenTextureVAO(){ int rVal = glGenVertexArrays(); glBindVertexArray(rVal); //vertices FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(12); VertexArrayBufferData.put(-1.0f); VertexArrayBufferData.put( 1.0f); VertexArrayBufferData.put(-1.0f); VertexArrayBufferData.put(-1.0f); VertexArrayBufferData.put( 1.0f); VertexArrayBufferData.put(-1.0f); VertexArrayBufferData.put(-1.0f); VertexArrayBufferData.put( 1.0f); VertexArrayBufferData.put( 1.0f); VertexArrayBufferData.put(-1.0f); VertexArrayBufferData.put( 1.0f); VertexArrayBufferData.put( 1.0f); VertexArrayBufferData.flip(); int vertexBuffer = glGenBuffers(); glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer); GL15.glBufferData(GL_ARRAY_BUFFER, VertexArrayBufferData, GL_STATIC_DRAW); glVertexAttribPointer(0, 2, GL_FLOAT, false, 0, 0); glEnableVertexAttribArray(0); //texture coords FloatBuffer TextureArrayBufferData = BufferUtils.createFloatBuffer(12); TextureArrayBufferData.put(0.0f); TextureArrayBufferData.put(1.0f); TextureArrayBufferData.put(0.0f); TextureArrayBufferData.put(0.0f); TextureArrayBufferData.put(1.0f); TextureArrayBufferData.put(0.0f); TextureArrayBufferData.put(0.0f); TextureArrayBufferData.put(1.0f); TextureArrayBufferData.put(1.0f); TextureArrayBufferData.put(0.0f); TextureArrayBufferData.put(1.0f); TextureArrayBufferData.put(1.0f); TextureArrayBufferData.flip(); int textureCoordBuffer = glGenBuffers(); glBindBuffer(GL_ARRAY_BUFFER, textureCoordBuffer); GL15.glBufferData(GL_ARRAY_BUFFER, TextureArrayBufferData, GL_STATIC_DRAW); glVertexAttribPointer(1, 2, GL_FLOAT, false, 0, 0); glEnableVertexAttribArray(1); return rVal; } 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); //apply mouse controls state if(Globals.controlHandler.isMouseVisible()){ Globals.controlHandler.showMouse(); } else { Globals.controlHandler.hideMouse(); } } 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 complexDraw(boolean setShader, boolean bufferStandardUniforms, boolean bufferNonStandardUniforms, boolean useMaterial, boolean useShadowMap, boolean setBones, boolean useLight){ if(setShader){ GL11.glDepthFunc(GL_LEQUAL); glUseProgram(shader.shaderProgram); } if(useMaterial){ 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); if(bufferStandardUniforms){ //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); if(setShader){ GL11.glDepthFunc(GL_LESS); } } }; skyboxmesh.mesh = null; // // VAO // skyboxmesh.vertexArrayObject = glGenVertexArrays(); glBindVertexArray(skyboxmesh.vertexArrayObject); float[] vertexcoords = { 100.0f, 100.0f, 100.0f, 100.0f, 100.0f,-100.0f, 100.0f,-100.0f, 100.0f, 100.0f,-100.0f,-100.0f, -100.0f, 100.0f, 100.0f, -100.0f, 100.0f,-100.0f, -100.0f,-100.0f, 100.0f, -100.0f,-100.0f,-100.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, 3); } 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, 3); } } 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; } public static Model createParticleModel(){ Model particleModel = new Model(); particleModel.meshes = new ArrayList(); particleModel.modelMatrix = new Matrix4f(); Mesh particleMesh = new Mesh(); particleMesh.mesh = null; // // VAO // particleMesh.vertexArrayObject = glGenVertexArrays(); glBindVertexArray(particleMesh.vertexArrayObject); float[] vertexcoords = { -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, }; // //Buffer data to GPU // try { particleMesh.vertexCount = vertexcoords.length / 3; FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(particleMesh.vertexCount * 3); float[] temp = new float[3]; for (int i = 0; i < particleMesh.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(); particleMesh.buffer_vertices(VertexArrayBufferData, 3); } catch (NullPointerException ex){ ex.printStackTrace(); } int[] facedata = { 0,1,2, 1,2,3, }; // // FACES // particleMesh.faceCount = facedata.length / 3; particleMesh.elementCount = facedata.length; IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(particleMesh.elementCount); for(int i = 0; i < particleMesh.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(); particleMesh.buffer_faces(elementArrayBufferData); // // TEXTURE COORDS // FloatBuffer texture_coords = BufferUtils.createFloatBuffer(8); float[] texturedata = { 0,0, 1,0, 0,1, 1,1 }; texture_coords.put(texturedata); texture_coords.flip(); particleMesh.buffer_texture_coords(texture_coords, 2); particleMesh.shader = ShaderProgram.loadSpecificShader("Shaders/particleBillboard/particleBillboard.vs", "Shaders/particleBillboard/particleBillboard.fs"); particleMesh.hasBones = false; glBindVertexArray(0); particleMesh.nodeID = "particleBillboard"; particleMesh.parent = particleModel; particleModel.meshes.add(particleMesh); return particleModel; } public static Model createPlaneModel(){ Model rVal = new Model(); rVal.meshes = new ArrayList(); rVal.modelMatrix = new Matrix4f(); Mesh planeMesh = new Mesh(); planeMesh.mesh = null; // // VAO // planeMesh.vertexArrayObject = glGenVertexArrays(); glBindVertexArray(planeMesh.vertexArrayObject); float[] vertexcoords = { -1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, -1.0f, -1.0f, 0.0f, 1.0f, -1.0f, 0.0f, }; // //Buffer data to GPU // try { planeMesh.vertexCount = vertexcoords.length / 3; FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(planeMesh.vertexCount * 3); float[] temp = new float[3]; for (int i = 0; i < planeMesh.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(); planeMesh.buffer_vertices(VertexArrayBufferData, 3); } catch (NullPointerException ex){ ex.printStackTrace(); } int[] facedata = { 0,1,2, 1,2,3, }; // // FACES // planeMesh.faceCount = facedata.length / 3; planeMesh.elementCount = facedata.length; IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(planeMesh.elementCount); for(int i = 0; i < planeMesh.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(); planeMesh.buffer_faces(elementArrayBufferData); // // TEXTURE COORDS // FloatBuffer texture_coords = BufferUtils.createFloatBuffer(8); float[] texturedata = { 0,1, 1,1, 0,0, 1,0 }; texture_coords.put(texturedata); texture_coords.flip(); planeMesh.buffer_texture_coords(texture_coords, 2); planeMesh.shader = ShaderProgram.loadSpecificShader("Shaders/plane/plane.vs", "Shaders/plane/plane.fs"); planeMesh.hasBones = false; glBindVertexArray(0); planeMesh.nodeID = "plane"; planeMesh.parent = rVal; rVal.meshes.add(planeMesh); return rVal; } }