382 lines
14 KiB
Java
382 lines
14 KiB
Java
/*
|
|
* 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<Vector3f> 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;
|
|
}
|
|
|
|
|
|
}
|