diff --git a/assets/Shaders/lightDepth/lightDepth.fs b/assets/Shaders/lightDepth/lightDepth.fs index 69fe18c3..68241c0b 100644 --- a/assets/Shaders/lightDepth/lightDepth.fs +++ b/assets/Shaders/lightDepth/lightDepth.fs @@ -1,8 +1,6 @@ - - #version 330 core void main() { - // gl_FragDepth = gl_FragCoord.z; + gl_FragDepth = gl_FragCoord.z; } \ No newline at end of file diff --git a/assets/Shaders/lightDepth/lightDepth.vs b/assets/Shaders/lightDepth/lightDepth.vs index 9bf8c16a..96a7ca09 100644 --- a/assets/Shaders/lightDepth/lightDepth.vs +++ b/assets/Shaders/lightDepth/lightDepth.vs @@ -1,4 +1,3 @@ - #version 330 core layout (location = 0) in vec3 aPos; layout (location = 2) in vec4 aWeights; diff --git a/assets/Shaders/particleBillboard/particleBillboard.fs b/assets/Shaders/particleBillboard/particleBillboard.fs new file mode 100644 index 00000000..fdc89d39 --- /dev/null +++ b/assets/Shaders/particleBillboard/particleBillboard.fs @@ -0,0 +1,191 @@ + + +#version 330 core +out vec4 FragColor; + +struct Material { + sampler2D diffuse; + sampler2D specular; + float shininess; +}; + +struct DirLight { + vec3 direction; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; + +struct PointLight { + vec3 position; + + float constant; + float linear; + float quadratic; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; + +struct SpotLight { + vec3 position; + vec3 direction; + float cutOff; + float outerCutOff; + + float constant; + float linear; + float quadratic; + + vec3 ambient; + vec3 diffuse; + vec3 specular; +}; + +#define NR_POINT_LIGHTS 10 + +in vec3 FragPos; +in vec3 Normal; +in vec2 TexCoord; +in vec4 FragPosLightSpace; + +uniform vec3 viewPos; +uniform DirLight dirLight; +uniform PointLight pointLights[NR_POINT_LIGHTS]; +uniform SpotLight spotLight; +uniform Material material; + +//texture stuff +// uniform sampler2D ourTexture; +uniform int hasTransparency; +// uniform sampler2D specularTexture; + +//light depth map +uniform sampler2D shadowMap; + + +// function prototypes +vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir); +vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir); +vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir); +float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal); + +void main(){ + if(hasTransparency == 1){ + if(texture(material.diffuse, TexCoord).a < 0.1){ + discard; + } + } + vec3 norm = normalize(Normal); + vec3 viewDir = normalize(viewPos - FragPos); + + + + vec3 result = CalcDirLight(dirLight, norm, viewDir); + //for(int i = 0; i < NR_POINT_LIGHTS; i++){ + // result += CalcPointLight(pointLights[i], norm, FragPos, viewDir); + //} + //result += CalcSpotLight(spotLight, norm, FragPos, viewDir); + + FragColor = vec4(result, texture(material.diffuse, TexCoord).a);//texture(ourTexture, TexCoord);//vec4(result, 1.0); +} + +// calculates the color when using a directional light. +vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir){ + vec3 lightDir = normalize(-light.direction); + // diffuse shading + float diff = max(dot(normal, lightDir), 0.0); + // specular shading + vec3 reflectDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + // combine results + vec3 texColor = texture(material.diffuse, TexCoord).rgb; + vec3 ambient = light.ambient; + vec3 diffuse = light.diffuse * diff; + //vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoord).rgb); + + + float shadow = ShadowCalculation(FragPosLightSpace, lightDir, normal); + + return ( ambient + (1.0-shadow) * 1.0 ) * texColor;// + specular); +} + + +// calculates the color when using a point light. +vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir){ + vec3 lightDir = normalize(light.position - fragPos); + // diffuse shading + float diff = max(dot(normal, lightDir), 0.0); + // specular shading + vec3 reflectDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + // attenuation + float distance = length(light.position - fragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); + // combine results + vec3 ambient = light.ambient * vec4(texture(material.diffuse, TexCoord)).xyz; + vec3 diffuse = light.diffuse * diff * vec4(texture(material.diffuse, TexCoord)).xyz; + vec3 specular = light.specular * spec * vec4(texture(material.specular, TexCoord)).xyz; + ambient *= attenuation; + diffuse *= attenuation; + specular *= attenuation; + return (ambient + diffuse + specular); +} + +// calculates the color when using a spot light. +vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir) +{ + vec3 lightDir = normalize(light.position - fragPos); + // diffuse shading + float diff = max(dot(normal, lightDir), 0.0); + // specular shading + vec3 reflectDir = reflect(-lightDir, normal); + float spec = pow(max(dot(viewDir, reflectDir), 0.0), material.shininess); + // attenuation + float distance = length(light.position - fragPos); + float attenuation = 1.0 / (light.constant + light.linear * distance + light.quadratic * (distance * distance)); + // spotlight intensity + float theta = dot(lightDir, normalize(-light.direction)); + float epsilon = light.cutOff - light.outerCutOff; + float intensity = clamp((theta - light.outerCutOff) / epsilon, 0.0, 1.0); + // combine results + vec3 ambient = light.ambient * vec3(texture(material.diffuse, TexCoord)); + vec3 diffuse = light.diffuse * diff * vec3(texture(material.diffuse, TexCoord)); + vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoord)); + ambient *= attenuation * intensity; + diffuse *= attenuation * intensity; + specular *= attenuation * intensity; + return (ambient + diffuse + specular); +} + + +float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal){ + + // perform perspective divide + vec3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w; + + //transform to NDC + projCoords = projCoords * 0.5 + 0.5; + + //get closest depth from light's POV + float closestDepth = texture(shadowMap, projCoords.xy).r; + + //get depth of current fragment + float currentDepth = projCoords.z; + + //calculate bias + float bias = max(0.05 * (1.0 - dot(normal, lightDir)), 0.005); + + //calculate shadow value + float shadow = currentDepth - bias > closestDepth ? 1.0 : 0.0; + + if(projCoords.z > 1.0){ + shadow = 0.0; + } + + // shadow = currentDepth; + + return shadow; +} \ No newline at end of file diff --git a/assets/Shaders/particleBillboard/particleBillboard.vs b/assets/Shaders/particleBillboard/particleBillboard.vs new file mode 100644 index 00000000..705dcba4 --- /dev/null +++ b/assets/Shaders/particleBillboard/particleBillboard.vs @@ -0,0 +1,48 @@ +//Vertex Shader +#version 330 core + + + +//input buffers +layout (location = 0) in vec3 aPos; +layout (location = 1) in vec3 aNormal; +layout (location = 4) in vec2 aTex; + + +//coordinate space transformation matrices +uniform mat4 transform; +uniform mat4 model; +uniform mat4 view; +uniform mat4 projection; +uniform mat4 lightSpaceMatrix; + + + +//output buffers +out vec3 Normal; +out vec3 FragPos; +out vec2 TexCoord; +out vec4 FragPosLightSpace; + + + + +void main() { + //normalize posiiton and normal + vec4 FinalVertex = vec4(aPos, 1.0); + vec4 FinalNormal = vec4(aNormal, 1.0); + + + //push frag, normal, and texture positions to fragment shader + FragPos = vec3(model * FinalVertex); + Normal = mat3(transpose(inverse(model))) * aNormal; + TexCoord = aTex; + + + //shadow map stuff + FragPosLightSpace = lightSpaceMatrix * vec4(FragPos, 1.0); + + + //set final position with opengl space + gl_Position = projection * view * model * FinalVertex; +} diff --git a/assets/Textures/spark1.png b/assets/Textures/spark1.png new file mode 100644 index 00000000..9c8dc27f Binary files /dev/null and b/assets/Textures/spark1.png differ diff --git a/src/main/java/electrosphere/engine/LoadingThread.java b/src/main/java/electrosphere/engine/LoadingThread.java index 5af3a3aa..32585142 100644 --- a/src/main/java/electrosphere/engine/LoadingThread.java +++ b/src/main/java/electrosphere/engine/LoadingThread.java @@ -16,6 +16,7 @@ import electrosphere.game.state.MacroSimulation; import electrosphere.game.server.terrain.manager.ServerTerrainManager; import electrosphere.game.server.world.ServerWorldData; import electrosphere.entity.types.attach.AttachUtils; +import electrosphere.entity.types.particle.ParticleUtils; import electrosphere.game.server.ai.creature.MindlessAttacker; import electrosphere.game.state.MicroSimulation; import electrosphere.logger.LoggerInterface; @@ -496,4 +497,6 @@ public class LoadingThread extends Thread { Entity sword = ItemUtils.spawnBasicItem("Katana"); AttachUtils.attachEntityToEntityAtBone(testHomie, sword, "Bone.020"); } + + } diff --git a/src/main/java/electrosphere/entity/CameraEntityUtils.java b/src/main/java/electrosphere/entity/CameraEntityUtils.java index a809c231..0080a7a9 100644 --- a/src/main/java/electrosphere/entity/CameraEntityUtils.java +++ b/src/main/java/electrosphere/entity/CameraEntityUtils.java @@ -60,11 +60,17 @@ public class CameraEntityUtils { } } - public static Matrix4f getCameraViewMatrix(Vector3f cameraEye){ + public static Matrix4f getCameraViewMatrix(Entity camera){ + Vector3f cameraCenter = new Vector3f(getCameraCenter(camera)).add(0,1,0); + Vector3f cameraEye = new Vector3f(cameraCenter).add(getCameraEye(camera)); + Vector3f cameraUp = new Vector3f(0,1.0f,0); +// System.out.println("eye: " + cameraEye); +// System.out.println("center: " + cameraCenter); +// System.out.println("up: " + cameraUp); Matrix4f rVal = new Matrix4f().setLookAt( cameraEye, //eye - new Vector3f(0,0,0), //center - new Vector3f(cameraEye).add(new Vector3f(0,1.0f,0)) // up + cameraCenter, //center + cameraUp // up ).scale(1.0f, 1.5f, 1.0f); return rVal; } diff --git a/src/main/java/electrosphere/entity/EntityDataStrings.java b/src/main/java/electrosphere/entity/EntityDataStrings.java index 37fac8ed..cd6696ed 100644 --- a/src/main/java/electrosphere/entity/EntityDataStrings.java +++ b/src/main/java/electrosphere/entity/EntityDataStrings.java @@ -119,4 +119,10 @@ public class EntityDataStrings { */ public static final String IDLE_TREE = "idleTree"; + /* + particle behavior tree + */ + public static final String IS_PARTICLE = "isParticle"; + public static final String PARTICLE_TREE = "particleTree"; + } diff --git a/src/main/java/electrosphere/entity/EntityManager.java b/src/main/java/electrosphere/entity/EntityManager.java index 44c8ae72..da54c012 100644 --- a/src/main/java/electrosphere/entity/EntityManager.java +++ b/src/main/java/electrosphere/entity/EntityManager.java @@ -23,6 +23,7 @@ public class EntityManager { static CopyOnWriteArrayList attackerList = new CopyOnWriteArrayList(); static CopyOnWriteArrayList creatureList = new CopyOnWriteArrayList(); static CopyOnWriteArrayList lifeStateList = new CopyOnWriteArrayList(); + static CopyOnWriteArrayList particleList = new CopyOnWriteArrayList(); public EntityManager(){ @@ -105,6 +106,14 @@ public class EntityManager { return lifeStateList; } + public void registerParticle(Entity e){ + particleList.add(e); + } + + public CopyOnWriteArrayList getParticles(){ + return particleList; + } + public void deregisterEntity(Entity e){ if(lightList.contains(e)){ lightList.remove(e); @@ -134,6 +143,9 @@ public class EntityManager { if(lifeStateList.contains(e)){ lifeStateList.remove(e); } + if(particleList.contains(e)){ + particleList.remove(e); + } } public void overrideEntityId(Entity e, int id){ diff --git a/src/main/java/electrosphere/entity/state/ParticleTree.java b/src/main/java/electrosphere/entity/state/ParticleTree.java new file mode 100644 index 00000000..00bf5458 --- /dev/null +++ b/src/main/java/electrosphere/entity/state/ParticleTree.java @@ -0,0 +1,63 @@ +package electrosphere.entity.state; + +import electrosphere.entity.Entity; +import electrosphere.entity.EntityUtils; +import electrosphere.main.Globals; +import org.joml.Vector3f; + +/** + * + * @author amaterasu + */ +public class ParticleTree { + Entity parent; + int maxLife; + int lifeCurrent; + Vector3f destination; + float velocity; + float acceleration; + + public ParticleTree(Entity parent, int maxLife, Vector3f destination, float velocity, float acceleration){ + this.parent = parent; + this.maxLife = maxLife; + this.destination = destination; + this.velocity = velocity; + this.acceleration = acceleration; + lifeCurrent = maxLife; + } + + public int getMaxLife() { + return maxLife; + } + + public int getLifeCurrent() { + return lifeCurrent; + } + + public Vector3f getDestination() { + return destination; + } + + public float getVelocity() { + return velocity; + } + + public float getAcceleration() { + return acceleration; + } + + public void simulate(){ + Vector3f parentPosition = EntityUtils.getPosition(parent); + parentPosition.add(new Vector3f(destination).mul(velocity)); + velocity = velocity - acceleration; + if(velocity < 0){ + velocity = 0; + acceleration = 0; + } + lifeCurrent--; + if(lifeCurrent <= 0){ + Globals.entityManager.deregisterEntity(parent); + } + } + +} diff --git a/src/main/java/electrosphere/entity/types/hitbox/HitboxUtils.java b/src/main/java/electrosphere/entity/types/hitbox/HitboxUtils.java index 8d181e2a..432f990b 100644 --- a/src/main/java/electrosphere/entity/types/hitbox/HitboxUtils.java +++ b/src/main/java/electrosphere/entity/types/hitbox/HitboxUtils.java @@ -5,7 +5,9 @@ import electrosphere.entity.EntityDataStrings; import electrosphere.entity.EntityUtils; import electrosphere.entity.types.attach.AttachUtils; import electrosphere.entity.types.item.ItemUtils; +import electrosphere.entity.types.life.LifeState; import electrosphere.entity.types.life.LifeUtils; +import electrosphere.game.server.effects.ParticleEffects; import electrosphere.main.Globals; import org.joml.Matrix4f; import org.joml.Quaternionf; @@ -117,7 +119,12 @@ public class HitboxUtils { if(isItem){ if(hitboxAttachParent != hurtboxParent){ + LifeState lifeState = LifeUtils.getLifeState(hurtboxParent); + int currentHp = lifeState.getLifeCurrent(); LifeUtils.getLifeState(hurtboxParent).damage(20); + if(currentHp > lifeState.getLifeCurrent()){ + ParticleEffects.spawnSparks(new Vector3f(EntityUtils.getPosition(hurtbox)).add(0,0.1f,0), 20, 40); + } if(!LifeUtils.getLifeState(hurtboxParent).isIsAlive()){ EntityUtils.getPosition(hurtboxParent).set(Globals.spawnPoint); LifeUtils.getLifeState(hurtboxParent).revive(); diff --git a/src/main/java/electrosphere/entity/types/particle/ParticleUtils.java b/src/main/java/electrosphere/entity/types/particle/ParticleUtils.java new file mode 100644 index 00000000..1f69ba88 --- /dev/null +++ b/src/main/java/electrosphere/entity/types/particle/ParticleUtils.java @@ -0,0 +1,47 @@ +package electrosphere.entity.types.particle; + +import electrosphere.entity.CameraEntityUtils; +import electrosphere.entity.Entity; +import electrosphere.entity.EntityDataStrings; +import electrosphere.entity.EntityUtils; +import electrosphere.entity.state.ParticleTree; +import electrosphere.main.Globals; +import org.joml.AxisAngle4f; +import org.joml.Matrix4f; +import org.joml.Quaternionf; +import org.joml.Vector3f; + +/** + * + * @author amaterasu + */ +public class ParticleUtils { + + + + public static Entity spawnParticle(String texture, int maxLife, Vector3f destination, float velocity, float acceleration){ + Entity rVal = EntityUtils.spawnDrawableEntity(Globals.particleBillboardModel); + EntityUtils.getActor(rVal).setTextureOverride(texture); + Globals.assetManager.addTexturePathtoQueue(texture); + ParticleTree particleTree = new ParticleTree(rVal, maxLife, destination, velocity, acceleration); + rVal.putData(EntityDataStrings.PARTICLE_TREE, particleTree); + rVal.putData(EntityDataStrings.IS_PARTICLE, true); + Globals.entityManager.registerParticle(rVal); + return rVal; + } + + public static void makeParticleBillboardFaceCamera(Entity particle){ + Vector3f cameraCenter = CameraEntityUtils.getCameraCenter(Globals.playerCamera); + Vector3f cameraEye = new Vector3f(CameraEntityUtils.getCameraEye(Globals.playerCamera)).add(cameraCenter).mul(-1.0f); + Vector3f particlePosition = EntityUtils.getPosition(particle); +// Vector3f cameraEye = new Vector3f(CameraEntityUtils.getCameraEye(Globals.playerCamera)).mul(1.0f,-1.0f,-1.0f); +// Vector3f directionVector = new Vector3f(cameraCenter).sub(cameraEye); + Matrix4f rotationMatrix = new Matrix4f(Globals.viewMatrix).invert(); + Quaternionf rotation = new Quaternionf(rotationMatrix.getRotation(new AxisAngle4f())); + EntityUtils.getRotation(particle).set(rotation); + } + + public static ParticleTree getParticleTree(Entity particle){ + return (ParticleTree)particle.getData(EntityDataStrings.PARTICLE_TREE); + } +} diff --git a/src/main/java/electrosphere/game/client/drawcell/DrawCell.java b/src/main/java/electrosphere/game/client/drawcell/DrawCell.java index 8a011bf0..492d3638 100644 --- a/src/main/java/electrosphere/game/client/drawcell/DrawCell.java +++ b/src/main/java/electrosphere/game/client/drawcell/DrawCell.java @@ -9,6 +9,7 @@ import electrosphere.renderer.Model; import electrosphere.renderer.ModelUtils; import electrosphere.renderer.ShaderProgram; import electrosphere.util.Utilities; +import org.joml.Quaternionf; import org.joml.Vector3f; /** @@ -78,7 +79,7 @@ public class DrawCell { String terrainModelPath = Globals.assetManager.registerModel(terrainModel); modelEntity = EntityUtils.spawnDrawableEntity(terrainModelPath); LoggerInterface.loggerRenderer.INFO("New cell @ " + cellX * dynamicInterpolationRatio + "," + cellY * dynamicInterpolationRatio); - EntityUtils.getPosition(modelEntity).set(new Vector3f(cellX * dynamicInterpolationRatio, 0.01f, cellY * dynamicInterpolationRatio)); + EntityUtils.getPosition(modelEntity).set(new Vector3f(cellX * dynamicInterpolationRatio, 0.0f, cellY * dynamicInterpolationRatio)); } public void retireCell(){ diff --git a/src/main/java/electrosphere/game/server/effects/ParticleEffects.java b/src/main/java/electrosphere/game/server/effects/ParticleEffects.java new file mode 100644 index 00000000..d8dcbf18 --- /dev/null +++ b/src/main/java/electrosphere/game/server/effects/ParticleEffects.java @@ -0,0 +1,28 @@ +package electrosphere.game.server.effects; + +import electrosphere.entity.Entity; +import electrosphere.entity.EntityUtils; +import electrosphere.entity.types.particle.ParticleUtils; +import java.util.Random; +import org.joml.Vector3f; + +/** + * + * @author amaterasu + */ +public class ParticleEffects { + + + public static void spawnSparks(Vector3f position, int min, int max){ + Random rand = new Random(); + int num = (int)(rand.nextFloat() * (max - min)) + min; + for(int i = 0; i < num; i++){ + Vector3f direction = new Vector3f(rand.nextFloat() - 0.5f,rand.nextFloat() - 0.5f,rand.nextFloat() - 0.5f).normalize(); + float velocity = rand.nextFloat() * 0.01f; + float acceleration = 0.005f; + Entity spark = ParticleUtils.spawnParticle("Textures/spark1.png", 15, direction, velocity, acceleration); + EntityUtils.getPosition(spark).set(position); + EntityUtils.getScale(spark).mul(0.03f); + } + } +} diff --git a/src/main/java/electrosphere/game/state/MicroSimulation.java b/src/main/java/electrosphere/game/state/MicroSimulation.java index 7d603957..2766b243 100644 --- a/src/main/java/electrosphere/game/state/MicroSimulation.java +++ b/src/main/java/electrosphere/game/state/MicroSimulation.java @@ -6,11 +6,13 @@ import electrosphere.entity.EntityUtils; import electrosphere.entity.state.AttackTree; import electrosphere.entity.state.IdleTree; import electrosphere.entity.state.MovementTree; +import electrosphere.entity.state.ParticleTree; import electrosphere.entity.types.creature.CreatureUtils; import electrosphere.entity.types.hitbox.HitboxUtils; import electrosphere.entity.types.item.ItemUtils; import electrosphere.entity.types.life.LifeState; import electrosphere.entity.types.life.LifeUtils; +import electrosphere.entity.types.particle.ParticleUtils; import electrosphere.main.Globals; import static electrosphere.main.Main.deltaTime; import electrosphere.renderer.Actor; @@ -63,6 +65,12 @@ public class MicroSimulation { LifeState lifeState = LifeUtils.getLifeState(lifeStateEntity); lifeState.simulate(); } + //particle state updates + for(Entity particle : Globals.entityManager.getParticles()){ + ParticleTree tree = ParticleUtils.getParticleTree(particle); + tree.simulate(); + ParticleUtils.makeParticleBillboardFaceCamera(particle); + } //update attached entity positions AttachUtils.updateAttachedEntityPositions(); //update hitbox positions diff --git a/src/main/java/electrosphere/main/Globals.java b/src/main/java/electrosphere/main/Globals.java index 338feb08..855209f1 100644 --- a/src/main/java/electrosphere/main/Globals.java +++ b/src/main/java/electrosphere/main/Globals.java @@ -152,6 +152,8 @@ public class Globals { public static Menu currentMenu; + public static String particleBillboardModel; + @@ -271,6 +273,8 @@ public class Globals { assetManager.registerModelToSpecificString(ModelUtils.createBitmapDisplay(), AssetDataStrings.ASSET_STRING_BITMAP_FONT); RawFontMap fontMap = FileLoadingUtils.loadObjectFromAssetPath("Textures/Fonts/myFontMap.json", RawFontMap.class); FontUtils.setFontDataMap(fontMap); + //particle billboard model + particleBillboardModel = assetManager.registerModel(RenderUtils.createParticleModel()); //black texture for backgrouns blackTexture = "Textures/b1.png"; Globals.assetManager.addTexturePathtoQueue("Textures/b1.png"); diff --git a/src/main/java/electrosphere/main/Main.java b/src/main/java/electrosphere/main/Main.java index 6947a4be..de8b1fec 100644 --- a/src/main/java/electrosphere/main/Main.java +++ b/src/main/java/electrosphere/main/Main.java @@ -216,7 +216,7 @@ public class Main { CameraEntityUtils.setCameraCenter(Globals.playerCamera, EntityUtils.getPosition(Globals.playerCharacter)); } - float cam_Player_Orbit_Magnitude = 1f; + float cam_Player_Orbit_Magnitude = 5f; cameraRotationVector.x = 0 + (float) Math.cos(yaw / 180.0f * Math.PI) * cam_Player_Orbit_Magnitude; cameraRotationVector.y = 0 + (float) Math.sin(pitch / 180.0f * Math.PI) * cam_Player_Orbit_Magnitude; cameraRotationVector.z = 0 + (float) Math.sin(yaw / 180.0f * Math.PI) * cam_Player_Orbit_Magnitude; @@ -224,7 +224,7 @@ public class Main { CameraEntityUtils.setCameraEye(Globals.playerCamera, cameraRotationVector); - Globals.viewMatrix = CameraEntityUtils.getCameraViewMatrix(CameraEntityUtils.getCameraEye(Globals.playerCamera)); + Globals.viewMatrix = CameraEntityUtils.getCameraViewMatrix(Globals.playerCamera); } diff --git a/src/main/java/electrosphere/renderer/Actor.java b/src/main/java/electrosphere/renderer/Actor.java index f16a20d6..259b2c9d 100644 --- a/src/main/java/electrosphere/renderer/Actor.java +++ b/src/main/java/electrosphere/renderer/Actor.java @@ -2,6 +2,7 @@ import electrosphere.main.Globals; import electrosphere.renderer.anim.Animation; +import electrosphere.renderer.texture.Texture; import org.joml.AxisAngle4f; import org.joml.Matrix4f; import org.joml.Quaternionf; @@ -14,6 +15,7 @@ import org.joml.Vector4f; */ public class Actor { String modelPath; + String textureOverride; String animation; double animationTime; boolean playingAnimation; @@ -80,7 +82,14 @@ public class Actor { playingAnimation = false; } } - model.draw(); + if(textureOverride != null){ + Texture overrideTextureObject = Globals.assetManager.fetchTexture(textureOverride); + if(overrideTextureObject != null){ + overrideTextureObject.bind(); + model.draw(true, true, false, false, true, true, true); + } + } + model.draw(true, true, false, true, true, true, true); } } @@ -89,7 +98,6 @@ public class Actor { if(model != null){ if(animation != null){ model.playAnimation(animation); - model.incrementTime(0.001); model.incrementTime(animationTime); if(model.currentAnimation == null){ playingAnimation = false; @@ -168,4 +176,8 @@ public class Actor { return rVal; } + public void setTextureOverride(String override){ + textureOverride = override; + } + } diff --git a/src/main/java/electrosphere/renderer/Mesh.java b/src/main/java/electrosphere/renderer/Mesh.java index e8f5450f..fe8472c8 100644 --- a/src/main/java/electrosphere/renderer/Mesh.java +++ b/src/main/java/electrosphere/renderer/Mesh.java @@ -411,135 +411,135 @@ public class 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 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 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 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(); @@ -577,76 +577,76 @@ public class Mesh { } - 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 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 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 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 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); @@ -657,16 +657,167 @@ public class Mesh { Object currentUniformRaw = uniforms.get(key); if(currentUniformRaw instanceof Matrix4f){ Matrix4f currentUniform = (Matrix4f)currentUniformRaw; - glUniformMatrix4fv(glGetUniformLocation(shader.shaderProgram, key), false, currentUniform.get(new float[16])); + glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, key), false, currentUniform.get(new float[16])); } if(currentUniformRaw instanceof Vector3f){ Vector3f currentUniform = (Vector3f)currentUniformRaw; - glUniform3fv(glGetUniformLocation(shader.shaderProgram, key), currentUniform.get(BufferUtils.createFloatBuffer(3))); + glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, key), currentUniform.get(BufferUtils.createFloatBuffer(3))); } if(currentUniformRaw instanceof Integer){ int currentInform = (Integer)currentUniformRaw; - glUniform1i(glGetUniformLocation(shader.shaderProgram, key), currentInform); + 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(light_buffer == null){ + float temp[] = new float[3]; + temp[0] = 0.2f; + temp[1] = -1.0f; + temp[2] = 0.3f; + glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.direction"), temp); + + temp[0] = 0.1f; + temp[1] = 0.1f; + temp[2] = 0.1f; + glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.ambient"), temp); + + temp[0] = 0.8f; + temp[1] = 0.8f; + temp[2] = 0.8f; + 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])); + + 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 { + GL20.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "model"), false, parent.modelMatrix.get(new float[16])); + } + } + + if(useMaterial){ + 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"), 1); + } + } + } + + + + glBindVertexArray(vertexArrayObject); + + 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 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.renderingEngine.getActiveShader().shaderProgram, currentUniform), false, bufferarray); + incrementer++; + } + } 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])); + } + + 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); + } } diff --git a/src/main/java/electrosphere/renderer/Model.java b/src/main/java/electrosphere/renderer/Model.java index f4f495ec..f107b267 100644 --- a/src/main/java/electrosphere/renderer/Model.java +++ b/src/main/java/electrosphere/renderer/Model.java @@ -186,14 +186,14 @@ public class Model { meshes = null; } - public void draw(){ + public void draw(boolean setShader, boolean bufferStandardUniforms, boolean bufferNonStandardUniforms, boolean useMaterial, boolean useShadowMap, boolean setBones, boolean useLight){ if(node_map != null && !node_map.isEmpty()){ update_node_transform(root_anim_node); } Iterator mesh_Iterator = meshes.iterator(); while(mesh_Iterator.hasNext()){ Mesh currentMesh = mesh_Iterator.next(); - currentMesh.draw(); + currentMesh.complexDraw(setShader, bufferStandardUniforms, bufferNonStandardUniforms, useMaterial, useShadowMap, setBones, useLight); } } @@ -344,13 +344,19 @@ public class Model { Iterator mesh_Iterator = meshes.iterator(); while(mesh_Iterator.hasNext()){ Mesh currentMesh = mesh_Iterator.next(); - currentMesh.drawForDepthBuffer(); + currentMesh.setUniform("model", modelMatrix); + if(currentMesh.hasBones){ + currentMesh.complexDraw(false, false, true, false, false, true, false); + } else { + currentMesh.setUniform("hasBones", 0); + currentMesh.complexDraw(false, false, true, false, false, false, false); + } } } public void drawUI(){ for(Mesh m : meshes){ - m.drawUI(); + m.complexDraw(true, false, true, true, false, false, false); } } @@ -367,4 +373,13 @@ public class Model { System.out.println(id); } } + + public Mesh getMesh(String meshName){ + for(Mesh mesh : meshes){ + if(mesh.nodeID.matches(meshName)){ + return mesh; + } + } + return null; + } } diff --git a/src/main/java/electrosphere/renderer/ModelUtils.java b/src/main/java/electrosphere/renderer/ModelUtils.java index 8e1f19b3..e2f9cf50 100644 --- a/src/main/java/electrosphere/renderer/ModelUtils.java +++ b/src/main/java/electrosphere/renderer/ModelUtils.java @@ -318,6 +318,8 @@ public class ModelUtils { glBindVertexArray(0); m.parent = rVal; + m.hasBones = false; + Material groundMat = new Material(); Globals.assetManager.addTexturePathtoQueue("/Textures/Ground/Dirt1.png"); groundMat.set_diffuse("/Textures/Ground/Dirt1.png"); diff --git a/src/main/java/electrosphere/renderer/RenderUtils.java b/src/main/java/electrosphere/renderer/RenderUtils.java index 8329a6fe..5e58828c 100644 --- a/src/main/java/electrosphere/renderer/RenderUtils.java +++ b/src/main/java/electrosphere/renderer/RenderUtils.java @@ -214,23 +214,27 @@ public class RenderUtils { Mesh skyboxmesh = new Mesh(){ @Override - public void draw(){ - GL11.glDepthFunc(GL_LEQUAL); - glUseProgram(shader.shaderProgram); + 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(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++; + 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++; + } } } @@ -238,17 +242,20 @@ public class RenderUtils { - - //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))); - + 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); - GL11.glDepthFunc(GL_LESS); + + if(setShader){ + GL11.glDepthFunc(GL_LESS); + } } }; @@ -436,6 +443,123 @@ public class RenderUtils { } - + 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; + } } diff --git a/src/main/java/electrosphere/renderer/RenderingEngine.java b/src/main/java/electrosphere/renderer/RenderingEngine.java index fca95f21..b995a515 100644 --- a/src/main/java/electrosphere/renderer/RenderingEngine.java +++ b/src/main/java/electrosphere/renderer/RenderingEngine.java @@ -79,8 +79,9 @@ public class RenderingEngine { static ShaderProgram lightDepthShaderProgram; static Framebuffer lightDepthBuffer; - public static boolean renderHitboxes = true; + public static boolean renderHitboxes = false; + ShaderProgram activeProgram; public void createOpenglContext(){ @@ -156,7 +157,7 @@ public class RenderingEngine { //first pass: generate depth map // if(Globals.RENDER_FLAG_RENDER_SHADOW_MAP){ - renderShadowMapFramebufferContent(); + renderShadowMapContent(); } @@ -164,7 +165,7 @@ public class RenderingEngine { Render content to the game framebuffer */ if(Globals.RENDER_FLAG_RENDER_SCREEN_FRAMEBUFFER_CONTENT){ - renderGameFramebufferContent(); + renderGameContent(); } @@ -209,28 +210,34 @@ public class RenderingEngine { } - static void renderShadowMapFramebufferContent(){ + static void renderShadowMapContent(){ Matrix4f modelTransformMatrix = new Matrix4f(); //set the viewport to shadow map size glViewport(0, 0, 4096, 4096); glEnable(GL_DEPTH_TEST); + + Globals.renderingEngine.setActiveShader(lightDepthShaderProgram); + lightDepthBuffer.bind(); glClear(GL_DEPTH_BUFFER_BIT); + float eyeX = -20.0f; + float eyeY = 40.0f; + float eyeZ = -10.0f; + float nearPlane = 0.001f; + float farPlane = (float)Math.sqrt(eyeX * eyeX + eyeY * eyeY + eyeZ * eyeZ) + 20.0f; //set matrices for light render - float near_plane = 0.001f, far_plane = 100.5f; - Matrix4f lightProjection = new Matrix4f().setOrtho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane);//glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane); - Matrix4f lightView = new Matrix4f().lookAt( - new Vector3f(-20.0f, 40.0f, -10.0f), - new Vector3f( 0.0f, 0.0f, 0.0f), + Matrix4f lightProjection = new Matrix4f().setOrtho(-10.0f, 10.0f, -10.0f, 10.0f, nearPlane, farPlane);//glm::ortho(-10.0f, 10.0f, -10.0f, 10.0f, near_plane, far_plane); + Matrix4f lightView = new Matrix4f().setLookAt( + new Vector3f(eyeX, eyeY, eyeZ).add(CameraEntityUtils.getCameraCenter(Globals.playerCamera)), + new Vector3f( 0.0f, 0.0f, 0.0f).add(CameraEntityUtils.getCameraCenter(Globals.playerCamera)), new Vector3f( 0.0f, 1.0f, 0.0f) ); Globals.lightDepthMatrix = new Matrix4f(lightProjection).mul(lightView); - glUseProgram(lightDepthShaderProgram.shaderProgram); - glUniformMatrix4fv(glGetUniformLocation(lightDepthShaderProgram.shaderProgram, "lightSpaceMatrix"), false, Globals.lightDepthMatrix.get(new float[16])); + glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "lightSpaceMatrix"), false, Globals.lightDepthMatrix.get(new float[16])); // glCullFace(GL_FRONT); @@ -241,24 +248,22 @@ public class RenderingEngine { for(Entity currentEntity : Globals.entityManager.getDrawable()){ //fetch actor Actor currentActor = EntityUtils.getActor(currentEntity); - currentActor.incrementAnimationTime(0.001); //calculate and apply model transform modelTransformMatrix.identity(); - modelTransformMatrix.translate(new Vector3f(EntityUtils.getPosition(currentEntity)).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)).sub(new Vector3f(0,1,0))); + modelTransformMatrix.translate(new Vector3f(EntityUtils.getPosition(currentEntity))); modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); modelTransformMatrix.scale(EntityUtils.getScale(currentEntity)); currentActor.applyModelMatrix(modelTransformMatrix); //draw currentActor.drawForDepthBuffer(); } + - - - //bind default framebuffer - glBindFramebuffer(GL_FRAMEBUFFER,0); //reset texture glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, 0); + //bind default framebuffer + glBindFramebuffer(GL_FRAMEBUFFER,0); //reset the viewport to screen size glViewport(0, 0, Globals.WINDOW_WIDTH, Globals.WINDOW_HEIGHT); //resume culling backface @@ -266,7 +271,7 @@ public class RenderingEngine { } - static void renderGameFramebufferContent(){ + static void renderGameContent(){ Matrix4f modelTransformMatrix = new Matrix4f(); @@ -297,7 +302,7 @@ public class RenderingEngine { // } //calculate and apply model transform modelTransformMatrix.identity(); - modelTransformMatrix.translate(new Vector3f(EntityUtils.getPosition(currentEntity)).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)).sub(new Vector3f(0,1,0))); + modelTransformMatrix.translate(new Vector3f(EntityUtils.getPosition(currentEntity))); modelTransformMatrix.rotate(EntityUtils.getRotation(currentEntity)); modelTransformMatrix.scale(EntityUtils.getScale(currentEntity)); currentActor.applyModelMatrix(modelTransformMatrix); @@ -326,32 +331,32 @@ public class RenderingEngine { if((hitboxModel = Globals.assetManager.fetchModel("Models/unitsphere.fbx")) != null){ Vector3f position = EntityUtils.getPosition(currentHitbox); modelTransformMatrix.identity(); - modelTransformMatrix.translate(new Vector3f(position).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)).sub(new Vector3f(0,1,0))); + modelTransformMatrix.translate(new Vector3f(position)); // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere modelTransformMatrix.scale(data.getRadius() * 2); hitboxModel.modelMatrix = modelTransformMatrix; - hitboxModel.draw(); + hitboxModel.draw(true, true, false, true, true, true, true); } } else if(data.getType().equals(EntityDataStrings.COLLISION_ENTITY_DATA_TYPE_HIT)){ if((hitboxModel = Globals.assetManager.fetchModel("Models/unitsphere_1.fbx")) != null){ Vector3f position = EntityUtils.getPosition(currentHitbox); modelTransformMatrix.identity(); - modelTransformMatrix.translate(new Vector3f(position).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)).sub(new Vector3f(0,1,0))); + modelTransformMatrix.translate(new Vector3f(position)); // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere modelTransformMatrix.scale(data.getRadius() * 2); hitboxModel.modelMatrix = modelTransformMatrix; - hitboxModel.draw(); + hitboxModel.draw(true, true, false, true, true, true, true); } } } else { if((hitboxModel = Globals.assetManager.fetchModel("Models/unitsphere_grey.fbx")) != null){ Vector3f position = EntityUtils.getPosition(currentHitbox); modelTransformMatrix.identity(); - modelTransformMatrix.translate(new Vector3f(position).sub(CameraEntityUtils.getCameraCenter(Globals.playerCamera)).sub(new Vector3f(0,1,0))); + modelTransformMatrix.translate(new Vector3f(position)); // modelTransformMatrix.translate(-0.25f, 0.0f, 0.5f); //center sphere modelTransformMatrix.scale(data.getRadius() * 2); hitboxModel.modelMatrix = modelTransformMatrix; - hitboxModel.draw(); + hitboxModel.draw(true, true, false, true, true, true, true); } } } @@ -384,7 +389,7 @@ public class RenderingEngine { //render full screen quad - glUseProgram(screenTextureShaders.shaderProgram); + Globals.renderingEngine.setActiveShader(screenTextureShaders); glBindVertexArray(screenTextureVAO); glBindTexture(GL_TEXTURE_2D, screenFramebuffer.getTexture()); // glBindTexture(GL_TEXTURE_2D, lightDepthBuffer.getTexture()); @@ -427,4 +432,13 @@ public class RenderingEngine { } + public void setActiveShader(ShaderProgram program){ + glUseProgram(program.shaderProgram); + activeProgram = program; + } + + public ShaderProgram getActiveShader(){ + return activeProgram; + } + }