Renderer/src/main/java/electrosphere/renderer/Mesh.java
2023-06-06 00:12:18 -04:00

770 lines
30 KiB
Java

package electrosphere.renderer;
import electrosphere.engine.Globals;
import electrosphere.engine.Main;
import electrosphere.entity.types.camera.CameraEntityUtils;
import electrosphere.logger.LoggerInterface;
import electrosphere.renderer.RenderPipelineState.SelectedShaderEnum;
import electrosphere.renderer.actor.ActorTextureMask;
import electrosphere.renderer.actor.instance.InstanceData;
import electrosphere.renderer.buffer.HomogenousInstancedArray;
import electrosphere.renderer.buffer.HomogenousUniformBuffer;
import electrosphere.renderer.buffer.ShaderAttribute;
import electrosphere.renderer.buffer.HomogenousUniformBuffer.HomogenousBufferTypes;
import electrosphere.renderer.light.LightManager;
import electrosphere.renderer.loading.ModelPretransforms;
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 java.util.Map;
import org.joml.Matrix4d;
import org.joml.Matrix4f;
import org.joml.Quaternionf;
import org.joml.Vector3f;
import org.joml.Vector4d;
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;
import org.lwjgl.opengl.GL40;
import org.lwjgl.opengl.GL45;
/**
*
* @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 ActorTextureMask textureMask;
public float vertexMinX;
public float vertexMaxX;
public float vertexMinY;
public float vertexMaxY;
public float vertexMinZ;
public float vertexMaxZ;
public ShaderProgram shader;
ShaderProgram oitShader;
int shaderBoneArrayLocation;
Material material;
public static Mesh create_mesh_from_aimesh(AIMesh mesh, ModelPretransforms.MeshMetadata metadata){
boolean has_bones = false;
boolean apply_lighting = true;
Mesh rVal = new Mesh();
rVal.mesh = mesh;
rVal.nodeID = mesh.mName().dataString();
//
// VAO
//
//Check for headless to not call gl functions when not running with gpu
if(!Globals.HEADLESS){
rVal.vertexArrayObject = glGenVertexArrays();
glBindVertexArray(rVal.vertexArrayObject);
}
//Basic checks
//check num vertices
int numVertices = mesh.mNumVertices();
AIVector3D.Buffer vertexData = mesh.mVertices();
// while(vertexData.hasRemaining()){
// vertexData.get();
// numVertices++;
// }
// vertexData = vertexData.rewind();
//check num normals
int numNormals = mesh.mNumVertices();
// 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);
}
Matrix4d vertexPretransform = new Matrix4d().identity();
if(metadata != null){
System.out.println("Pretransforming");
vertexPretransform.translationRotateScale(metadata.getOffset(), metadata.getRotation(), metadata.getScale());
}
//
//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;
}
Vector4d transformedVertex = vertexPretransform.transform(new Vector4d(x,y,z,1.0));
temp[0] = (float)transformedVertex.x;
temp[1] = (float)transformedVertex.y;
temp[2] = (float)transformedVertex.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();
if(!Globals.HEADLESS){
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;
}
if(!Globals.HEADLESS){
rVal.shader = ShaderProgram.smart_assemble_shader(has_bones, apply_lighting);
rVal.oitShader = ShaderProgram.smartAssembleOITProgram(has_bones, apply_lighting);
}
if(!Globals.HEADLESS){
glBindVertexArray(0);
}
return rVal;
}
public Mesh(){
}
public void buffer_vertices(FloatBuffer verticies, int vertexDimension){
if(!Globals.HEADLESS){
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){
if(!Globals.HEADLESS){
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){
if(!Globals.HEADLESS){
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){
if(!Globals.HEADLESS){
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){
if(!Globals.HEADLESS){
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){
if(!Globals.HEADLESS){
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){
if(!Globals.HEADLESS){
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 setTextureMask(ActorTextureMask textureMask){
this.textureMask = textureMask;
}
public void setMaterial(Material input){
this.material = input;
}
public void generateShader(SelectedShaderEnum selectedShader, boolean hasBones, boolean applyLighting){
switch(selectedShader){
case PRIMARY: {
shader = ShaderProgram.smart_assemble_shader(hasBones, applyLighting);
} break;
case OIT: {
oitShader = ShaderProgram.smartAssembleOITProgram(hasBones, applyLighting);
} break;
}
}
public void setShader(ShaderProgram shader){
this.shader = shader;
}
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);
}
}
}
/**
* Sends a buffer to the gpu
* @param uniformTypeMap The type of the buffer
* @param buffers The buffer
*/
void bufferInstanceData(
RenderPipelineState renderPipelineState,
Map<ShaderAttribute,Object> buffers,
Map<ShaderAttribute,HomogenousInstancedArray> uniformGlBufferMap
){
for(ShaderAttribute attribute : buffers.keySet()){
HomogenousInstancedArray buffer = uniformGlBufferMap.get(attribute);
buffer.updateBuffer(buffers.get(attribute), 0);
buffer.bind(renderPipelineState);
// switch(uniformTypeMap.get(uniformName)){
// case VEC3F: {
// FloatBuffer buffer = (FloatBuffer)buffers.get(key);
// int bufferIndex = GL31.glGetUniformBlockIndex(shaderIndex, "Lights");
// //bind that position to the slot '2'
// GL31.glUniformBlockBinding(shaderIndex, bufferIndex, BIND_POINT);
// //bind our buffer to slot '2' as well
// GL31.glBindBufferBase(GL_UNIFORM_BUFFER, BIND_POINT, uboIndex);
// //alternatively if want to use range, do glBindBufferRange(GL_UNIFORM_BUFFER, 2, uboExampleBlock, 0, 152);
// } break;
// case VEC3D: {
// } break;
// case VEC4F: {
// } break;
// case VEC4D: {
// } break;
// case DOUBLE: {
// } break;
// case FLOAT: {
// } break;
// case INT: {
// } break;
// }
}
}
/**
* Draws the mesh
* @param renderPipelineState The state of the render pipeline
*/
public void complexDraw(RenderPipelineState renderPipelineState){
if(renderPipelineState.getUseMeshShader()){
ShaderProgram selectedProgram = null;
switch(renderPipelineState.getSelectedShader()){
case PRIMARY: {
selectedProgram = shader;
} break;
case OIT: {
selectedProgram = oitShader;
} break;
}
if(selectedProgram == null){
selectedProgram = shader;
}
Globals.renderingEngine.setActiveShader(renderPipelineState, selectedProgram);
}
if(renderPipelineState.getUseLight()){
//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){
//don't buffer as the light manager hasn't initialized
} else {
LightManager lightManager = Globals.renderingEngine.getLightManager();
lightManager.bindBuffer(Globals.renderingEngine.getActiveShader().shaderProgram);
}
}
if(renderPipelineState.getUseMaterial() && textureMask == null){
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(textureMask != null){
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 : textureMask.getTextures()){
// System.out.println(texture.getPath() + " => groundTextures[" + i + "]" + "=>" + (i));
if(texture != null){
texture.bind(5+i);
}
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, textureMask.getUniformNames().get(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(renderPipelineState.getUseShadowMap()){
glActiveTexture(GL_TEXTURE3);
glBindTexture(GL_TEXTURE_2D, Globals.shadowMapTextureLoc);
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "shadowMap"), 3);
}
if(renderPipelineState.getUseBones()){
//
//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){
Matrix4d currentMat = new Matrix4d(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);
// }
GL45.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, currentUniform), false, bufferarray);
} else {
// System.out.println("Bonename: " + boneName);
// System.exit(1);
GL45.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, currentUniform), false, new float[16]);
}
incrementer++;
}
} else {
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "hasBones"), 0);
}
} else {
glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "hasBones"), 0);
}
if(renderPipelineState.getBufferStandardUniforms()){
//buffer model/view/proj matrices
GL45.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.getCurrentFrame());
glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "time"), (float)Main.getCurrentFrame());
}
if(renderPipelineState.getBufferNonStandardUniforms()){
bufferAllUniforms();
}
if(renderPipelineState.getInstanced()){
InstanceData instanceData = renderPipelineState.getInstanceData();
Map<ShaderAttribute,Object> buffers = instanceData.getCpuBufferMap();
Map<ShaderAttribute,HomogenousInstancedArray> glBufferMap = instanceData.getGlBufferMap();
bufferInstanceData(renderPipelineState, buffers, glBufferMap);
}
if(renderPipelineState.getInstanced()){
GL45.glDrawElementsInstanced(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, 0, renderPipelineState.getInstanceData().getDrawCount());
} else {
GL11.glDrawElements(GL_TRIANGLES, elementCount, GL_UNSIGNED_INT, 0);
}
glBindVertexArray(0);
}
}