923 lines
38 KiB
Java
923 lines
38 KiB
Java
package electrosphere.renderer;
|
|
|
|
import electrosphere.entity.types.camera.CameraEntityUtils;
|
|
import electrosphere.logger.LoggerInterface;
|
|
import electrosphere.main.Globals;
|
|
import electrosphere.main.Main;
|
|
import electrosphere.renderer.light.LightManager;
|
|
import electrosphere.renderer.texture.Texture;
|
|
import java.nio.FloatBuffer;
|
|
import java.nio.IntBuffer;
|
|
import java.util.ArrayList;
|
|
import java.util.HashMap;
|
|
import java.util.Iterator;
|
|
import java.util.List;
|
|
import org.joml.Matrix4f;
|
|
import org.joml.Vector3f;
|
|
import org.lwjgl.BufferUtils;
|
|
import org.lwjgl.PointerBuffer;
|
|
import org.lwjgl.assimp.AIBone;
|
|
import org.lwjgl.assimp.AIFace;
|
|
import org.lwjgl.assimp.AIMesh;
|
|
import org.lwjgl.assimp.AIVector2D;
|
|
import org.lwjgl.assimp.AIVector3D;
|
|
import org.lwjgl.assimp.AIVertexWeight;
|
|
import static org.lwjgl.opengl.ARBVertexBufferObject.*;
|
|
import org.lwjgl.opengl.GL11;
|
|
import static org.lwjgl.opengl.GL11.GL_FALSE;
|
|
import static org.lwjgl.opengl.GL11.GL_FLOAT;
|
|
import static org.lwjgl.opengl.GL11.GL_INT;
|
|
import static org.lwjgl.opengl.GL11.GL_TRIANGLES;
|
|
import static org.lwjgl.opengl.GL11.GL_UNSIGNED_INT;
|
|
import org.lwjgl.opengl.GL15;
|
|
import org.lwjgl.opengl.GL15C;
|
|
|
|
import static org.lwjgl.opengl.GL15.GL_ARRAY_BUFFER;
|
|
import static org.lwjgl.opengl.GL15.GL_ELEMENT_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.*;
|
|
import static org.lwjgl.opengl.GL20.glGetUniformLocation;
|
|
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;
|
|
|
|
/**
|
|
*
|
|
* @author satellite
|
|
*/
|
|
public class Mesh {
|
|
|
|
//THIS IS NOT GUARANTEED TO BE THE PARENT MODEL THAT THIS WAS LOADED IN
|
|
//THIS CAN BE POST-LOAD SET IN MODEL VIA MODELMASK BEHAVIOR
|
|
public Model parent;
|
|
public String nodeID;
|
|
public AIMesh mesh;
|
|
public int vertexBuffer;
|
|
public int normalBuffer;
|
|
public int elementArrayBuffer;
|
|
public int elementCount;
|
|
public int faceCount;
|
|
public int vertexArrayObject;
|
|
public int vertexCount;
|
|
public int normalCount;
|
|
public int boneWeightBuffer;
|
|
public int boneIndexBuffer;
|
|
public int boneCount;
|
|
public int textureCoordBuffer;
|
|
public int textureCoordCount;
|
|
//THIS IS NOT GUARANTEED TO BE THE PARENT MODEL THAT THIS WAS LOADED IN
|
|
//THIS CAN BE POST-LOAD SET IN MODEL VIA MODELMASK BEHAVIOR
|
|
public ArrayList<Bone> bones = new ArrayList<Bone>();
|
|
public ArrayList<String> bone_id_list = new ArrayList<String>();
|
|
HashMap<String,Object> uniforms = new HashMap<String,Object>();
|
|
int bone_map_size = 0;
|
|
boolean hasBones = true;
|
|
public boolean hasTextureCoords = true;
|
|
|
|
public List<Texture> textureList = new ArrayList<Texture>();
|
|
public boolean useTextureList;
|
|
public String textureListArrayUniformName;
|
|
|
|
public float vertexMinX;
|
|
public float vertexMaxX;
|
|
public float vertexMinY;
|
|
public float vertexMaxY;
|
|
public float vertexMinZ;
|
|
public float vertexMaxZ;
|
|
|
|
public ShaderProgram shader;
|
|
|
|
int shaderBoneArrayLocation;
|
|
|
|
Material material;
|
|
|
|
public static Mesh create_mesh_from_aimesh(AIMesh mesh){
|
|
boolean has_bones = false;
|
|
boolean apply_lighting = true;
|
|
|
|
Mesh rVal = new Mesh();
|
|
rVal.mesh = mesh;
|
|
rVal.nodeID = mesh.mName().dataString();
|
|
|
|
//
|
|
// VAO
|
|
//
|
|
rVal.vertexArrayObject = glGenVertexArrays();
|
|
glBindVertexArray(rVal.vertexArrayObject);
|
|
|
|
|
|
|
|
//Basic checks
|
|
//check num vertices
|
|
int numVertices = 0;
|
|
AIVector3D.Buffer vertexData = mesh.mVertices();
|
|
while(vertexData.hasRemaining()){
|
|
vertexData.get();
|
|
numVertices++;
|
|
}
|
|
vertexData = vertexData.rewind();
|
|
//check num normals
|
|
int numNormals = 0;
|
|
AIVector3D.Buffer normalData = mesh.mNormals();
|
|
while(normalData.hasRemaining()){
|
|
normalData.get();
|
|
numNormals++;
|
|
}
|
|
normalData.rewind();
|
|
if(numVertices != numNormals){
|
|
System.out.println("Catastrophic failure: Number of vertices =/= Number of normals");
|
|
System.exit(1);
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
//Buffer data to GPU
|
|
//
|
|
vertexData.rewind();
|
|
|
|
try {
|
|
rVal.vertexCount = mesh.mNumVertices();
|
|
FloatBuffer VertexArrayBufferData = BufferUtils.createFloatBuffer(rVal.vertexCount * 3);
|
|
float[] temp = new float[3];
|
|
boolean definedDimensions = false;
|
|
float minX = 0, maxX = 0, minY = 0, maxY = 0, minZ = 0, maxZ = 0;
|
|
for (int i = 0; i < rVal.vertexCount; i++) {
|
|
AIVector3D vertex = vertexData.get();
|
|
float x = vertex.x();
|
|
float y = vertex.y();
|
|
float z = vertex.z();
|
|
if(definedDimensions){
|
|
if(x < minX){ minX = x; }
|
|
if(x > maxX){ maxX = x; }
|
|
if(y < minY){ minY = y; }
|
|
if(y > maxY){ maxY = y; }
|
|
if(z < minZ){ minZ = z; }
|
|
if(z > maxZ){ maxZ = z; }
|
|
} else {
|
|
definedDimensions = true;
|
|
minX = maxX = x;
|
|
minY = maxY = y;
|
|
minZ = maxZ = z;
|
|
}
|
|
temp[0] = x;
|
|
temp[1] = y;
|
|
temp[2] = z;
|
|
VertexArrayBufferData.put(temp);
|
|
}
|
|
|
|
rVal.vertexMaxX = maxX;
|
|
rVal.vertexMinX = minX;
|
|
rVal.vertexMaxY = maxY;
|
|
rVal.vertexMinY = minY;
|
|
rVal.vertexMaxZ = maxZ;
|
|
rVal.vertexMinZ = minZ;
|
|
|
|
VertexArrayBufferData.flip();
|
|
rVal.buffer_vertices(VertexArrayBufferData, 3);
|
|
} catch (NullPointerException ex){
|
|
ex.printStackTrace();
|
|
}
|
|
//
|
|
// NORMALS
|
|
//
|
|
AIVector3D.Buffer normals = mesh.mNormals();
|
|
try {
|
|
rVal.normalCount = mesh.mNumVertices();
|
|
FloatBuffer NormalArrayBufferData;
|
|
if(rVal.normalCount > 0){
|
|
NormalArrayBufferData = BufferUtils.createFloatBuffer(rVal.normalCount * 3);
|
|
float[] temp = new float[3];
|
|
for (int i = 0; i < rVal.normalCount; i++) {
|
|
AIVector3D normal = normals.get(i);
|
|
temp[0] = normal.x();
|
|
temp[1] = normal.y();
|
|
temp[2] = normal.z();
|
|
NormalArrayBufferData.put(temp);
|
|
}
|
|
NormalArrayBufferData.flip();
|
|
rVal.buffer_normals(NormalArrayBufferData, 3);
|
|
}
|
|
} catch (NullPointerException ex){
|
|
ex.printStackTrace();
|
|
}
|
|
//
|
|
// FACES
|
|
//
|
|
rVal.faceCount = mesh.mNumFaces();
|
|
rVal.elementCount = rVal.faceCount * 3;
|
|
IntBuffer elementArrayBufferData = BufferUtils.createIntBuffer(rVal.elementCount);
|
|
AIFace.Buffer facesBuffer = mesh.mFaces();
|
|
for(int i = 0; i < rVal.faceCount; i++){
|
|
AIFace face = facesBuffer.get(i);
|
|
if(face.mNumIndices() != 3){
|
|
throw new IllegalStateException("AIFace.mNumIndices() != 3");
|
|
}
|
|
elementArrayBufferData.put(face.mIndices());
|
|
}
|
|
elementArrayBufferData.flip();
|
|
rVal.buffer_faces(elementArrayBufferData);
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
// TEXTURE COORDINATES
|
|
//
|
|
if(mesh.mTextureCoords().capacity() > 0){
|
|
AIVector3D.Buffer texturecoords = mesh.mTextureCoords(0);
|
|
try {
|
|
rVal.textureCoordCount = mesh.mTextureCoords(0).capacity();
|
|
FloatBuffer TextureArrayBufferData;
|
|
if(rVal.textureCoordCount > 0){
|
|
TextureArrayBufferData = BufferUtils.createFloatBuffer(rVal.textureCoordCount * 2);
|
|
float[] temp = new float[2];
|
|
for (int i = 0; i < rVal.textureCoordCount; i++) {
|
|
AIVector3D normal = texturecoords.get(i);
|
|
temp[0] = normal.x();
|
|
temp[1] = normal.y();
|
|
// temp[2] = normal.z();
|
|
TextureArrayBufferData.put(temp);
|
|
}
|
|
TextureArrayBufferData.flip();
|
|
rVal.buffer_texture_coords(TextureArrayBufferData, 2);
|
|
}
|
|
} catch (NullPointerException ex){
|
|
ex.printStackTrace();
|
|
}
|
|
//System.out.println("Enabled texture coordinates");
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//
|
|
//Read in bones
|
|
//AND buffer data (weights) to GPU
|
|
//
|
|
PointerBuffer boneBuffer = mesh.mBones();
|
|
if(boneBuffer != null){
|
|
has_bones = true;
|
|
while(boneBuffer.hasRemaining()){
|
|
long currentAddr = boneBuffer.get();
|
|
AIBone currentBoneData = AIBone.createSafe(currentAddr);
|
|
// System.out.println("Num weights: " + currentBoneData.mNumWeights());
|
|
Bone currentBone = new Bone();
|
|
currentBone.boneID = currentBoneData.mName().dataString();
|
|
currentBone.inverseBindPoseMatrix = electrosphere.util.Utilities.convertAIMatrix(currentBoneData.mOffsetMatrix());
|
|
currentBone.numWeights = currentBoneData.mNumWeights();
|
|
currentBone.weights = new HashMap<Integer,Float>();
|
|
Iterator<AIVertexWeight> weightIterator = currentBoneData.mWeights().iterator();
|
|
while(weightIterator.hasNext()){
|
|
AIVertexWeight currentWeightData = weightIterator.next();
|
|
currentBone.weights.put(currentWeightData.mVertexId(), currentWeightData.mWeight());
|
|
}
|
|
rVal.bones.add(currentBone);
|
|
rVal.bone_id_list.add(currentBone.boneID);
|
|
}
|
|
rVal.boneCount = rVal.bones.size();
|
|
FloatBuffer boneWeightDataBuffer = BufferUtils.createFloatBuffer(4 * rVal.vertexCount);//FloatBuffer.allocate(4 * vertexCount);
|
|
FloatBuffer boneIndexDataBuffer = BufferUtils.createFloatBuffer(4 * rVal.vertexCount);//IntBuffer.allocate(4 * vertexCount);
|
|
Iterator<Bone> boneIterator;
|
|
for(int i = 0; i < rVal.vertexCount; i++){
|
|
float[] weight = new float[4];
|
|
float[] index = new float[4];
|
|
int boneCounter = 0;
|
|
boneIterator = rVal.bones.iterator();
|
|
while(boneIterator.hasNext()){
|
|
Bone currentBone = boneIterator.next();
|
|
float boneVal = 0;
|
|
if(currentBone.weights.get(i) != null){
|
|
boneVal = currentBone.weights.get(i);
|
|
}
|
|
if(boneVal > 0){
|
|
if(boneVal > weight[0]){
|
|
weight[3] = weight[2];
|
|
weight[2] = weight[1];
|
|
weight[1] = weight[0];
|
|
weight[0] = boneVal;
|
|
index[3] = index[2];
|
|
index[2] = index[1];
|
|
index[1] = index[0];
|
|
index[0] = boneCounter;
|
|
// if(rVal.nodeID.equals("Torso")){
|
|
// System.out.println(index[3] + " " + index[2] + " " + index[1] + " " + index[0]);
|
|
// }
|
|
} else if(boneVal > weight[1]){
|
|
weight[3] = weight[2];
|
|
weight[2] = weight[1];
|
|
weight[1] = boneVal;
|
|
index[3] = index[2];
|
|
index[2] = index[1];
|
|
index[1] = boneCounter;
|
|
} else if(boneVal > weight[2]){
|
|
weight[3] = weight[2];
|
|
weight[2] = boneVal;
|
|
index[3] = index[2];
|
|
index[2] = boneCounter;
|
|
} else if(boneVal > weight[3]){
|
|
weight[3] = boneVal;
|
|
index[3] = boneCounter;
|
|
}
|
|
}
|
|
boneCounter++;
|
|
}
|
|
float total = weight[0] + weight[1] + weight[2] + weight[3];
|
|
if(total != 1.0f){
|
|
weight[0] = weight[0] * (1.0f / total);
|
|
weight[1] = weight[1] * (1.0f / total);
|
|
weight[2] = weight[2] * (1.0f / total);
|
|
weight[3] = weight[3] * (1.0f / total);
|
|
}
|
|
boneIndexDataBuffer.put(index);
|
|
boneWeightDataBuffer.put(weight);
|
|
}
|
|
boneIndexDataBuffer.flip();
|
|
boneWeightDataBuffer.flip();
|
|
|
|
|
|
rVal.boneWeightBuffer = glGenBuffers();
|
|
glBindBuffer(GL_ARRAY_BUFFER, rVal.boneWeightBuffer);
|
|
GL15.glBufferData(GL_ARRAY_BUFFER, boneWeightDataBuffer, GL_STATIC_DRAW);
|
|
glVertexAttribPointer(2, 4, GL_FLOAT, false, 0, 0);
|
|
glEnableVertexAttribArray(2);
|
|
|
|
|
|
rVal.boneIndexBuffer = glGenBuffers();
|
|
glBindBuffer(GL_ARRAY_BUFFER, rVal.boneIndexBuffer);
|
|
GL15.glBufferData(GL_ARRAY_BUFFER, boneIndexDataBuffer, GL_STATIC_DRAW);
|
|
glVertexAttribPointer(3, 4, GL_FLOAT, false, 0, 0);
|
|
glEnableVertexAttribArray(3);
|
|
} else {
|
|
rVal.hasBones = false;
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
rVal.shader = ShaderProgram.smart_assemble_shader(has_bones, apply_lighting);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
glBindVertexArray(0);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return rVal;
|
|
}
|
|
|
|
|
|
public Mesh(){
|
|
|
|
}
|
|
|
|
// public void draw() {
|
|
// glUseProgram(shader.shaderProgram);
|
|
//
|
|
// //Until we switch to uniform buffer objects we will have to buffer lighting data here manually each time we draw
|
|
// //side note: :(
|
|
// if(light_buffer == null){
|
|
// float temp[] = new float[3];
|
|
// temp[0] = 0.2f;
|
|
// temp[1] = -1.0f;
|
|
// temp[2] = 0.3f;
|
|
// glUniform3fv(glGetUniformLocation(shader.shaderProgram, "dirLight.direction"), temp);
|
|
//
|
|
// temp[0] = 0.1f;
|
|
// temp[1] = 0.1f;
|
|
// temp[2] = 0.1f;
|
|
// glUniform3fv(glGetUniformLocation(shader.shaderProgram, "dirLight.ambient"), temp);
|
|
//
|
|
// temp[0] = 0.8f;
|
|
// temp[1] = 0.8f;
|
|
// temp[2] = 0.8f;
|
|
// glUniform3fv(glGetUniformLocation(shader.shaderProgram, "dirLight.diffuse"), temp);
|
|
//
|
|
// temp[0] = 0.1f;
|
|
// temp[1] = 0.1f;
|
|
// temp[2] = 0.1f;
|
|
// glUniform3fv(glGetUniformLocation(shader.shaderProgram, "dirLight.specular"), temp);
|
|
//
|
|
// temp[0] = 32f;
|
|
// glUniform1fv(glGetUniformLocation(shader.shaderProgram, "material.shininess"), temp);
|
|
//
|
|
// GL20.glUniformMatrix4fv(glGetUniformLocation(shader.shaderProgram, "model"), false, parent.modelMatrix.get(new float[16]));
|
|
//
|
|
// Vector3f cam_Loc = CameraEntityUtils.getCameraEye(Globals.playerCamera);//Globals.cameraVisible.pos_Center;
|
|
// temp[0] = cam_Loc.x;
|
|
// temp[1] = cam_Loc.y;
|
|
// temp[2] = cam_Loc.z;
|
|
// glUniform3fv(glGetUniformLocation(shader.shaderProgram, "viewPos"), temp);
|
|
// } else {
|
|
// GL20.glUniformMatrix4fv(glGetUniformLocation(shader.shaderProgram, "model"), false, parent.modelMatrix.get(new float[16]));
|
|
// }
|
|
//
|
|
//
|
|
// if(material == null){
|
|
// Globals.materialDefault.apply_material(0,1);
|
|
// GL20.glUniform1i(glGetUniformLocation(shader.shaderProgram, "hasTransparency"), 0);
|
|
// } else {
|
|
// material.apply_material();
|
|
// if(material.hasTransparency){
|
|
// GL20.glUniform1i(glGetUniformLocation(shader.shaderProgram, "hasTransparency"), 1);
|
|
// } else {
|
|
// GL20.glUniform1i(glGetUniformLocation(shader.shaderProgram, "hasTransparency"), 1);
|
|
// }
|
|
// }
|
|
//
|
|
//
|
|
//
|
|
// glBindVertexArray(vertexArrayObject);
|
|
//
|
|
//
|
|
// glActiveTexture(GL_TEXTURE3);
|
|
// glBindTexture(GL_TEXTURE_2D, Globals.shadowMapTextureLoc);
|
|
// glUniform1i(glGetUniformLocation(shader.shaderProgram, "shadowMap"), 3);
|
|
//
|
|
//
|
|
//
|
|
// //
|
|
// //Handle bones
|
|
// //
|
|
// if(bones != null && !bones.isEmpty()){
|
|
// glUniform1i(shader.shaderVertexHasBonesLoc, 1);
|
|
// glUniform1i(shader.shaderVertexNumBonesLoc, bones.size());
|
|
// Iterator<String> boneIterator = bone_id_list.iterator();
|
|
// float bufferarray[] = new float[16];
|
|
// int incrementer = 0;
|
|
// while (boneIterator.hasNext()){
|
|
// Bone currentBone = parent.boneMap.get(boneIterator.next());
|
|
// Matrix4f currentMat = new Matrix4f(currentBone.final_transform);
|
|
// currentMat.get(bufferarray);
|
|
// String currentUniform = "bones[" + incrementer + "]";
|
|
// GL20.glUniformMatrix4fv(glGetUniformLocation(shader.shaderProgram, currentUniform), false, bufferarray);
|
|
// incrementer++;
|
|
// }
|
|
// } else {
|
|
// glUniform1i(shader.shaderVertexHasBonesLoc, 0);
|
|
// }
|
|
//
|
|
//
|
|
//
|
|
// //buffer model/view/proj matrices
|
|
// glUniformMatrix4fv(shader.shaderVertexModelLoc, false, parent.modelMatrix.get(new float[16]));
|
|
// glUniformMatrix4fv(shader.shaderVertexViewLoc, false, Globals.viewMatrix.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)));
|
|
// glUniformMatrix4fv(glGetUniformLocation(shader.shaderProgram, "lightSpaceMatrix"), false, Globals.lightDepthMatrix.get(new float[16]));
|
|
//
|
|
// //
|
|
// //
|
|
// //Testing Lights
|
|
// //
|
|
// //
|
|
// float test_Light_Data[] = new float[3];
|
|
// test_Light_Data[0] = 0.2f;
|
|
// test_Light_Data[1] = -1.0f;
|
|
// test_Light_Data[2] = 0.3f;
|
|
// glUniform3fv(glGetUniformLocation(shader.shaderProgram, "dirLight.direction"), test_Light_Data);
|
|
//
|
|
// test_Light_Data = new float[3];
|
|
// test_Light_Data[0] = 0.3f;
|
|
// test_Light_Data[1] = 0.3f;
|
|
// test_Light_Data[2] = 0.3f;
|
|
// glUniform3fv(glGetUniformLocation(shader.shaderProgram, "dirLight.ambient"), test_Light_Data);
|
|
//
|
|
// test_Light_Data = new float[3];
|
|
// test_Light_Data[0] = 0.5f;
|
|
// test_Light_Data[1] = 0.5f;
|
|
// test_Light_Data[2] = 0.5f;
|
|
// glUniform3fv(glGetUniformLocation(shader.shaderProgram, "dirLight.diffuse"), test_Light_Data);
|
|
//
|
|
// Vector3f cam_Loc = CameraEntityUtils.getCameraEye(Globals.playerCamera);
|
|
// test_Light_Data = new float[3];
|
|
// test_Light_Data[0] = cam_Loc.x;
|
|
// test_Light_Data[1] = cam_Loc.y;
|
|
// test_Light_Data[2] = cam_Loc.z;
|
|
// glUniform3fv(glGetUniformLocation(shader.shaderProgram, "viewPos"), test_Light_Data);
|
|
//
|
|
//
|
|
// GL11.glDrawElements(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, 0);
|
|
// glBindVertexArray(0);
|
|
// }
|
|
|
|
public void buffer_vertices(FloatBuffer verticies, int vertexDimension){
|
|
vertexBuffer = glGenBuffers();
|
|
glBindBuffer(GL_ARRAY_BUFFER, vertexBuffer);
|
|
GL15.glBufferData(GL_ARRAY_BUFFER, verticies, GL_STATIC_DRAW);
|
|
glVertexAttribPointer(0, vertexDimension, GL_FLOAT, false, 0, 0);
|
|
glEnableVertexAttribArray(0);
|
|
}
|
|
|
|
public void buffer_normals(FloatBuffer normals, int normalDimension){
|
|
normalBuffer = glGenBuffers();
|
|
glBindBuffer(GL_ARRAY_BUFFER, normalBuffer);
|
|
GL15.glBufferData(GL_ARRAY_BUFFER, normals, GL_STATIC_DRAW);
|
|
glVertexAttribPointer(1, normalDimension, GL_FLOAT, false, 0, 0);
|
|
glEnableVertexAttribArray(1);
|
|
}
|
|
|
|
public void buffer_faces(IntBuffer faces){
|
|
elementArrayBuffer = glGenBuffers();
|
|
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, elementArrayBuffer);
|
|
GL15.glBufferData(GL_ELEMENT_ARRAY_BUFFER, faces, GL_STATIC_DRAW);
|
|
elementCount = faces.capacity();
|
|
}
|
|
|
|
public void buffer_texture_coords(FloatBuffer coords, int textureDimension){
|
|
textureCoordBuffer = glGenBuffers();
|
|
glBindBuffer(GL_ARRAY_BUFFER, textureCoordBuffer);
|
|
GL15.glBufferData(GL_ARRAY_BUFFER, coords, GL_STATIC_DRAW);
|
|
glVertexAttribPointer(4, textureDimension, GL_FLOAT, false, 0, 0);
|
|
glEnableVertexAttribArray(4);
|
|
}
|
|
|
|
public void bufferCustomFloatAttribArray(FloatBuffer buffer, int bufferDimension, int attribIndex){
|
|
int customBuffer = glGenBuffers();
|
|
glBindBuffer(GL_ARRAY_BUFFER, customBuffer);
|
|
GL15.glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
|
|
glVertexAttribPointer(attribIndex, bufferDimension, GL_FLOAT, false, 0, 0);
|
|
glEnableVertexAttribArray(attribIndex);
|
|
}
|
|
|
|
public void bufferCustomIntAttribArray(IntBuffer buffer, int bufferDimension, int attribIndex){
|
|
int customBuffer = glGenBuffers();
|
|
glBindBuffer(GL_ARRAY_BUFFER, customBuffer);
|
|
GL15.glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
|
|
glVertexAttribPointer(attribIndex, bufferDimension, GL_INT, false, 0, 0);
|
|
glEnableVertexAttribArray(attribIndex);
|
|
}
|
|
|
|
public void bufferCustomUIntAttribArray(IntBuffer buffer, int bufferDimension, int attribIndex){
|
|
int customBuffer = glGenBuffers();
|
|
glBindBuffer(GL_ARRAY_BUFFER, customBuffer);
|
|
GL15.glBufferData(GL_ARRAY_BUFFER, buffer, GL_STATIC_DRAW);
|
|
glVertexAttribPointer(attribIndex, bufferDimension, GL_UNSIGNED_INT, false, 0, 0);
|
|
glEnableVertexAttribArray(attribIndex);
|
|
}
|
|
|
|
public void setTextureList(List<Texture> textureList, String uniformName){
|
|
this.textureList = textureList;
|
|
useTextureList = true;
|
|
textureListArrayUniformName = uniformName;
|
|
}
|
|
|
|
public void setMaterial(Material input){
|
|
this.material = input;
|
|
}
|
|
|
|
|
|
// public void drawForDepthBuffer(){
|
|
// /*
|
|
//
|
|
// !!!!!!!!!!!!!!!!!THERE IS NO SHADER PROGRAM HERE!!!!!!!!!!!!!!!!!!!!!!!!!!
|
|
//
|
|
// The shader program is set in the main render function to make things easier
|
|
//
|
|
// */
|
|
//
|
|
//
|
|
// glBindVertexArray(vertexArrayObject);
|
|
//
|
|
//
|
|
//
|
|
//
|
|
// //
|
|
// //Handle bones
|
|
// //
|
|
// if(bones != null && !bones.isEmpty()){
|
|
// glUniform1i(glGetUniformLocation(Globals.depthMapShaderProgramLoc, "numBones"), bones.size());
|
|
// glUniform1i(glGetUniformLocation(Globals.depthMapShaderProgramLoc, "hasBones"), 1);
|
|
// Iterator<String> boneIterator = bone_id_list.iterator();
|
|
// float bufferarray[] = new float[16];
|
|
// int incrementer = 0;
|
|
// while (boneIterator.hasNext()){
|
|
// Bone currentBone = parent.boneMap.get(boneIterator.next());
|
|
// Matrix4f currentMat = new Matrix4f(currentBone.final_transform);
|
|
// currentMat.get(bufferarray);
|
|
// String currentUniform = "bones[" + incrementer + "]";
|
|
// GL20.glUniformMatrix4fv(glGetUniformLocation(Globals.depthMapShaderProgramLoc, currentUniform), false, bufferarray);
|
|
// incrementer++;
|
|
// }
|
|
// } else {
|
|
// glUniform1i(glGetUniformLocation(Globals.depthMapShaderProgramLoc, "hasBones"), 0);
|
|
// }
|
|
//
|
|
// //buffer model/view/proj matrices
|
|
// glUniformMatrix4fv(glGetUniformLocation(Globals.depthMapShaderProgramLoc, "model"), false, parent.modelMatrix.get(new float[16]));
|
|
// glUniformMatrix4fv(glGetUniformLocation(Globals.depthMapShaderProgramLoc, "lightSpaceMatrix"), false, Globals.lightDepthMatrix.get(new float[16]));
|
|
//
|
|
//
|
|
// GL11.glDrawElements(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, 0);
|
|
// glBindVertexArray(0);
|
|
// }
|
|
|
|
// public void drawUI(){
|
|
// glUseProgram(shader.shaderProgram);
|
|
//
|
|
// glBindVertexArray(vertexArrayObject);
|
|
//
|
|
// if(material == null){
|
|
// Globals.materialDefault.apply_material(0,1);
|
|
// GL20.glUniform1i(glGetUniformLocation(shader.shaderProgram, "hasTransparency"), 0);
|
|
// } else {
|
|
// material.apply_material();
|
|
// if(material.hasTransparency){
|
|
// GL20.glUniform1i(glGetUniformLocation(shader.shaderProgram, "hasTransparency"), 1);
|
|
// } else {
|
|
// GL20.glUniform1i(glGetUniformLocation(shader.shaderProgram, "hasTransparency"), 1);
|
|
// }
|
|
// }
|
|
//
|
|
// //buffers contents of uniforms map to gpu
|
|
// bufferAllUniforms();
|
|
//
|
|
// glUniformMatrix4fv(glGetUniformLocation(shader.shaderProgram, "model"), false, parent.modelMatrix.get(new float[16]));
|
|
//
|
|
// GL11.glDrawElements(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, 0);
|
|
// glBindVertexArray(0);
|
|
// }
|
|
|
|
public void setUniform(String key, Object o){
|
|
uniforms.put(key, o);
|
|
}
|
|
|
|
void bufferAllUniforms(){
|
|
for(String key : uniforms.keySet()){
|
|
Object currentUniformRaw = uniforms.get(key);
|
|
if(currentUniformRaw instanceof Matrix4f){
|
|
Matrix4f currentUniform = (Matrix4f)currentUniformRaw;
|
|
glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, key), false, currentUniform.get(new float[16]));
|
|
}
|
|
if(currentUniformRaw instanceof Vector3f){
|
|
Vector3f currentUniform = (Vector3f)currentUniformRaw;
|
|
glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, key), currentUniform.get(BufferUtils.createFloatBuffer(3)));
|
|
}
|
|
if(currentUniformRaw instanceof Integer){
|
|
int currentInform = (Integer)currentUniformRaw;
|
|
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, key), currentInform);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public void complexDraw(
|
|
boolean setShader,
|
|
boolean bufferStandardUniforms,
|
|
boolean bufferNonStandardUniforms,
|
|
boolean useMaterial,
|
|
boolean useShadowMap,
|
|
boolean setBones,
|
|
boolean useLight){
|
|
|
|
if(setShader){
|
|
Globals.renderingEngine.setActiveShader(shader);
|
|
}
|
|
|
|
if(useLight){
|
|
//Until we switch to uniform buffer objects we will have to buffer lighting data here manually each time we draw
|
|
//side note: :(
|
|
if(Globals.renderingEngine.getLightManager() == null){
|
|
|
|
//this needs to get transformed by the view matrix and isn't
|
|
Vector3f lightLoc = new Vector3f(0.2f,-1.0f,0.3f);
|
|
float temp[] = new float[3];
|
|
temp[0] = lightLoc.x;
|
|
temp[1] = lightLoc.y;
|
|
temp[2] = lightLoc.z;
|
|
glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.direction"), temp);
|
|
|
|
temp[0] = 0.4f;
|
|
temp[1] = 0.4f;
|
|
temp[2] = 0.4f;
|
|
glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.ambient"), temp);
|
|
|
|
temp[0] = 0.3f;
|
|
temp[1] = 0.3f;
|
|
temp[2] = 0.3f;
|
|
glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.diffuse"), temp);
|
|
|
|
temp[0] = 0.1f;
|
|
temp[1] = 0.1f;
|
|
temp[2] = 0.1f;
|
|
glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.specular"), temp);
|
|
|
|
temp[0] = 32f;
|
|
glUniform1fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "material.shininess"), temp);
|
|
|
|
// GL20.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "model"), false, parent.modelMatrix.get(new float[16]));
|
|
|
|
//set in standard uniforms
|
|
//
|
|
// Vector3f cam_Loc = CameraEntityUtils.getCameraEye(Globals.playerCamera);//Globals.cameraVisible.pos_Center;
|
|
// temp[0] = cam_Loc.x;
|
|
// temp[1] = cam_Loc.y;
|
|
// temp[2] = cam_Loc.z;
|
|
// glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "viewPos"), temp);
|
|
} else {
|
|
LightManager lightManager = Globals.renderingEngine.getLightManager();
|
|
lightManager.bindBuffer(Globals.renderingEngine.getActiveShader().shaderProgram);
|
|
// GL20.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "model"), false, parent.modelMatrix.get(new float[16]));
|
|
}
|
|
}
|
|
|
|
if(useMaterial && !useTextureList){
|
|
if(material == null){
|
|
Globals.materialDefault.apply_material(0,1);
|
|
GL20.glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "hasTransparency"), 0);
|
|
} else {
|
|
material.apply_material();
|
|
if(material.hasTransparency){
|
|
GL20.glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "hasTransparency"), 1);
|
|
} else {
|
|
GL20.glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "hasTransparency"), 0);
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
glBindVertexArray(vertexArrayObject);
|
|
|
|
|
|
|
|
if(useTextureList){
|
|
int i = 0;
|
|
// glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "groundTextures"), 5);
|
|
// for(int j = 1; j < 15; j++){
|
|
// textureList.get(0).bind(j);
|
|
// }
|
|
for(Texture texture : textureList){
|
|
// System.out.println(texture.getPath() + " => groundTextures[" + i + "]" + "=>" + (i));
|
|
if(texture != null){
|
|
texture.bind(5+i);
|
|
}
|
|
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "groundTextures[" + i + "]"),5+i);
|
|
i++;
|
|
}
|
|
// for(int j = i; j < 10; j++){
|
|
// glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "groundTextures[" + j + "]"),6+j);
|
|
// }
|
|
// glActiveTexture(GL_TEXTURE0);
|
|
}
|
|
|
|
if(useShadowMap){
|
|
glActiveTexture(GL_TEXTURE3);
|
|
glBindTexture(GL_TEXTURE_2D, Globals.shadowMapTextureLoc);
|
|
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "shadowMap"), 3);
|
|
}
|
|
|
|
|
|
if(setBones){
|
|
//
|
|
//Handle bones
|
|
//
|
|
if(bones != null && !bones.isEmpty()){
|
|
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "hasBones"), 1);
|
|
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "numBones"), bones.size());
|
|
Iterator<String> boneIterator = bone_id_list.iterator();
|
|
float bufferarray[] = new float[16];
|
|
int incrementer = 0;
|
|
while (boneIterator.hasNext()){
|
|
String boneName = boneIterator.next();
|
|
Bone currentBone = parent.boneMap.get(boneName);
|
|
String currentUniform = "bones[" + incrementer + "]";
|
|
if(currentBone != null){
|
|
Matrix4f currentMat = new Matrix4f(currentBone.final_transform);
|
|
currentMat.get(bufferarray);
|
|
// if(boneName.equals("Torso")){
|
|
// System.out.println("Found torso bone");
|
|
// System.out.println(currentUniform);
|
|
// System.out.println(currentMat);
|
|
// System.exit(0);
|
|
// }
|
|
GL20.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, currentUniform), false, bufferarray);
|
|
} else {
|
|
// System.out.println("Bonename: " + boneName);
|
|
// System.exit(1);
|
|
GL20.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, currentUniform), false, new float[16]);
|
|
}
|
|
incrementer++;
|
|
}
|
|
} else {
|
|
glUniform1i(Globals.renderingEngine.getActiveShader().shaderVertexHasBonesLoc, 0);
|
|
}
|
|
} else {
|
|
glUniform1i(Globals.renderingEngine.getActiveShader().shaderVertexHasBonesLoc, 0);
|
|
}
|
|
|
|
|
|
if(bufferStandardUniforms){
|
|
//buffer model/view/proj matrices
|
|
glUniformMatrix4fv(Globals.renderingEngine.getActiveShader().shaderVertexModelLoc, false, parent.modelMatrix.get(new float[16]));
|
|
glUniformMatrix4fv(Globals.renderingEngine.getActiveShader().shaderVertexViewLoc, false, Globals.viewMatrix.get(new float[16]));
|
|
glUniformMatrix4fv(Globals.renderingEngine.getActiveShader().shaderVertexProjectionLoc, false, Globals.projectionMatrix.get(new float[16]));
|
|
glUniform3fv(Globals.renderingEngine.getActiveShader().shaderVertexViewPosLoc, CameraEntityUtils.getCameraEye(Globals.playerCamera).get(BufferUtils.createFloatBuffer(3)));
|
|
glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "lightSpaceMatrix"), false, Globals.lightDepthMatrix.get(new float[16]));
|
|
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "frame"), (int)Main.frameCount);
|
|
glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "time"), (float)Main.frameCount);
|
|
}
|
|
|
|
if(bufferNonStandardUniforms){
|
|
bufferAllUniforms();
|
|
}
|
|
|
|
// if(shadowMapShader){
|
|
// glUniformMatrix4fv(glGetUniformLocation(Globals.depthMapShaderProgramLoc, "model"), false, parent.modelMatrix.get(new float[16]));
|
|
// glUniformMatrix4fv(glGetUniformLocation(Globals.depthMapShaderProgramLoc, "lightSpaceMatrix"), false, Globals.lightDepthMatrix.get(new float[16]));
|
|
// }
|
|
|
|
// if(useLight){
|
|
// //
|
|
// //
|
|
// //Testing Lights
|
|
// //
|
|
// //
|
|
// float test_Light_Data[] = new float[3];
|
|
// test_Light_Data[0] = 0.2f;
|
|
// test_Light_Data[1] = -1.0f;
|
|
// test_Light_Data[2] = 0.3f;
|
|
// glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.direction"), test_Light_Data);
|
|
|
|
// test_Light_Data = new float[3];
|
|
// test_Light_Data[0] = 0.3f;
|
|
// test_Light_Data[1] = 0.3f;
|
|
// test_Light_Data[2] = 0.3f;
|
|
// glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.ambient"), test_Light_Data);
|
|
|
|
// test_Light_Data = new float[3];
|
|
// test_Light_Data[0] = 0.5f;
|
|
// test_Light_Data[1] = 0.5f;
|
|
// test_Light_Data[2] = 0.5f;
|
|
// glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.diffuse"), test_Light_Data);
|
|
|
|
// Vector3f cam_Loc = CameraEntityUtils.getCameraEye(Globals.playerCamera);
|
|
// test_Light_Data = new float[3];
|
|
// test_Light_Data[0] = cam_Loc.x;
|
|
// test_Light_Data[1] = cam_Loc.y;
|
|
// test_Light_Data[2] = cam_Loc.z;
|
|
// glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "viewPos"), test_Light_Data);
|
|
// }
|
|
|
|
|
|
|
|
GL11.glDrawElements(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, 0);
|
|
glBindVertexArray(0);
|
|
}
|
|
}
|