diff --git a/assets/Shaders/skysphere/skysphere.fs b/assets/Shaders/skysphere/skysphere.fs new file mode 100644 index 00000000..7e03e86f --- /dev/null +++ b/assets/Shaders/skysphere/skysphere.fs @@ -0,0 +1,76 @@ + + +#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; + + +void main(){ + if(hasTransparency == 1){ + if(texture(material.diffuse, TexCoord).a < 0.1){ + discard; + } + } + FragColor = texture(material.diffuse, TexCoord); +} \ No newline at end of file diff --git a/assets/Shaders/skysphere/skysphere.vs b/assets/Shaders/skysphere/skysphere.vs new file mode 100644 index 00000000..705dcba4 --- /dev/null +++ b/assets/Shaders/skysphere/skysphere.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/src/main/java/electrosphere/engine/LoadingThread.java b/src/main/java/electrosphere/engine/LoadingThread.java index 3da839c2..99f4373d 100644 --- a/src/main/java/electrosphere/engine/LoadingThread.java +++ b/src/main/java/electrosphere/engine/LoadingThread.java @@ -527,12 +527,14 @@ public class LoadingThread extends Thread { Entity skybox = EntityUtils.spawnDrawableEntity("Models/skyboxSphere.fbx"); EntityUtils.getRotation(skybox).rotateX((float)(-Math.PI/2.0f)); EntityUtils.getScale(skybox).mul(2000.0f); + Globals.assetManager.queueOverrideMeshShader("Models/skyboxSphere.fbx", "Sphere", "Shaders/skysphere/skysphere.vs", "Shaders/skysphere/skysphere.fs"); //cloud ring pseudo skybox Entity cloudRing = EntityUtils.spawnDrawableEntity("Models/cloudRing.fbx"); EntityUtils.getRotation(cloudRing).rotateX((float)(-Math.PI/2.0f)); EntityUtils.getScale(cloudRing).mul(1000.0f); Globals.entityManager.registerBehaviorTree(new ApplyRotationTree(cloudRing,new Quaternionf().rotationZ(0.0001f))); + Globals.assetManager.queueOverrideMeshShader("Models/cloudRing.fbx", "Sphere", "Shaders/skysphere/skysphere.vs", "Shaders/skysphere/skysphere.fs"); } diff --git a/src/main/java/electrosphere/engine/assetmanager/AssetManager.java b/src/main/java/electrosphere/engine/assetmanager/AssetManager.java index 1e183fdc..128f3461 100644 --- a/src/main/java/electrosphere/engine/assetmanager/AssetManager.java +++ b/src/main/java/electrosphere/engine/assetmanager/AssetManager.java @@ -1,12 +1,15 @@ package electrosphere.engine.assetmanager; import electrosphere.audio.AudioBuffer; +import electrosphere.renderer.Mesh; import electrosphere.renderer.Model; +import electrosphere.renderer.ShaderProgram; import electrosphere.renderer.texture.Texture; import electrosphere.util.ModelLoader; -import java.util.HashMap; + import java.util.LinkedList; import java.util.List; +import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; @@ -17,14 +20,15 @@ import java.util.concurrent.CopyOnWriteArrayList; */ public class AssetManager { - ConcurrentHashMap modelsLoadedIntoMemory = new ConcurrentHashMap(); - CopyOnWriteArrayList modelsInQueue = new CopyOnWriteArrayList(); + Map modelsLoadedIntoMemory = new ConcurrentHashMap(); + List modelsInQueue = new CopyOnWriteArrayList(); + List shaderOverrides = new CopyOnWriteArrayList(); - ConcurrentHashMap texturesLoadedIntoMemory = new ConcurrentHashMap(); - CopyOnWriteArrayList texturesInQueue = new CopyOnWriteArrayList(); + Map texturesLoadedIntoMemory = new ConcurrentHashMap(); + List texturesInQueue = new CopyOnWriteArrayList(); - ConcurrentHashMap audioLoadedIntoMemory = new ConcurrentHashMap(); - CopyOnWriteArrayList audioInQueue = new CopyOnWriteArrayList(); + Map audioLoadedIntoMemory = new ConcurrentHashMap(); + List audioInQueue = new CopyOnWriteArrayList(); @@ -48,6 +52,7 @@ public class AssetManager { audioInQueue.remove(currentPath); audioLoadedIntoMemory.put(currentPath, new AudioBuffer(currentPath)); } + performMeshOverrides(); } @@ -93,6 +98,30 @@ public class AssetManager { modelsLoadedIntoMemory.put(s,m); } + public void queueOverrideMeshShader(String modelName, String meshName, String vertPath, String fragPath){ + MeshShaderOverride override = new MeshShaderOverride(modelName,meshName,vertPath,fragPath); + shaderOverrides.add(override); + } + + public void performMeshOverrides(){ + List toRemove = new LinkedList(); + for(MeshShaderOverride shaderOverride : shaderOverrides){ + Model model = null; + if((model = fetchModel(shaderOverride.modelName)) != null){ + for(Mesh mesh : model.meshes){ + if(mesh.nodeID.equals(shaderOverride.getMeshName())){ + mesh.shader = ShaderProgram.loadSpecificShader(shaderOverride.vertPath, shaderOverride.fragPath); + } + } + toRemove.add(shaderOverride); + } + } + for(MeshShaderOverride shaderOverride : toRemove){ + shaderOverrides.remove(shaderOverride); + } + } + + diff --git a/src/main/java/electrosphere/engine/assetmanager/MeshShaderOverride.java b/src/main/java/electrosphere/engine/assetmanager/MeshShaderOverride.java new file mode 100644 index 00000000..7debfcbf --- /dev/null +++ b/src/main/java/electrosphere/engine/assetmanager/MeshShaderOverride.java @@ -0,0 +1,33 @@ +package electrosphere.engine.assetmanager; + +public class MeshShaderOverride { + + String modelName; + String meshName; + String vertPath; + String fragPath; + + public MeshShaderOverride(String modelName, String meshName, String vertPath, String fragPath){ + this.modelName = modelName; + this.meshName = meshName; + this.vertPath = vertPath; + this.fragPath = fragPath; + } + + public String getModelName(){ + return modelName; + } + + public String getMeshName(){ + return meshName; + } + + public String getVertPath(){ + return vertPath; + } + + public String getFragPath(){ + return fragPath; + } + +} diff --git a/src/main/java/electrosphere/renderer/ShaderProgram.java b/src/main/java/electrosphere/renderer/ShaderProgram.java index bee505fc..3ed1f847 100644 --- a/src/main/java/electrosphere/renderer/ShaderProgram.java +++ b/src/main/java/electrosphere/renderer/ShaderProgram.java @@ -167,6 +167,8 @@ public class ShaderProgram { return rVal; } + + public static ShaderProgram load_default_shader_program(){