diff --git a/assets/Models/campfire1.fbx b/assets/Models/campfire1.fbx new file mode 100644 index 00000000..16c3007f Binary files /dev/null and b/assets/Models/campfire1.fbx differ diff --git a/assets/Shaders/FragmentShader.fs b/assets/Shaders/FragmentShader.fs index 8d6dac35..ef094fb8 100644 --- a/assets/Shaders/FragmentShader.fs +++ b/assets/Shaders/FragmentShader.fs @@ -1,60 +1,53 @@ - - #version 330 core + +#define NR_POINT_LIGHTS 10 + out vec4 FragColor; + +layout (std140) uniform Lights { + // this is how many because we have to align + // bytes it SHOULD in multiples of 16, this + // take it where it ACTUALLY is + // + //refer: https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL + // + // base alignment aligned offset + //direct light + vec3 dLDirection; // 16 0 + vec3 dLAmbient; // 16 16 + vec3 dLDiffuse; // 16 32 + vec3 dLSpecular; // 16 48 + + //point light + vec3 pLposition[NR_POINT_LIGHTS]; // 16*10 64 + float pLconstant[NR_POINT_LIGHTS]; // 16*10 224 + float pLlinear[NR_POINT_LIGHTS]; // 16*10 384 + float pLquadratic[NR_POINT_LIGHTS]; // 16*10 544 + vec3 pLambient[NR_POINT_LIGHTS]; // 16*10 704 + vec3 pLdiffuse[NR_POINT_LIGHTS]; // 16*10 864 + vec3 pLspecular[NR_POINT_LIGHTS]; // 16*10 1024 + + //for a total size of 1184 + +}; + 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 DirLight dirLight; +// uniform PointLight pointLights[NR_POINT_LIGHTS]; +// uniform SpotLight spotLight; uniform Material material; //texture stuff @@ -67,9 +60,9 @@ 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); +vec3 CalcDirLight(vec3 normal, vec3 viewDir); +vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir); +vec3 CalcSpotLight(vec3 normal, vec3 fragPos, vec3 viewDir); float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal); void main(){ @@ -83,7 +76,10 @@ void main(){ - vec3 result = CalcDirLight(dirLight, norm, viewDir); + vec3 result = CalcDirLight(norm, viewDir); + for(int i = 0; i < NR_POINT_LIGHTS; i++){ + result += CalcPointLight(i, norm, FragPos, viewDir); + } //for(int i = 0; i < NR_POINT_LIGHTS; i++){ // result += CalcPointLight(pointLights[i], norm, FragPos, viewDir); //} @@ -94,8 +90,8 @@ void main(){ } // calculates the color when using a directional light. -vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir){ - vec3 lightDir = normalize(-light.direction); +vec3 CalcDirLight(vec3 normal, vec3 viewDir){ + vec3 lightDir = normalize(-dLDirection); // diffuse shading float diff = max(dot(normal, lightDir), 0.0); // specular shading @@ -103,62 +99,61 @@ vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir){ // 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 diffuse = dLDiffuse * diff; //vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoord).rgb); float shadow = ShadowCalculation(FragPosLightSpace, lightDir, normal); - return ( ambient + (1.0-shadow) * diffuse ) * texColor;// + specular); + return ( dLAmbient + (1.0-shadow) * diffuse ) * 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); +// vec3 CalcPointLight(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 point light. +vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir){ + vec3 lightDir = normalize(pLposition[i] - 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); + // 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)); + float distance = length(pLposition[i] - fragPos); + float attenuation = 1.0 / (pLconstant[i] + pLlinear[i] * distance + pLquadratic[i] * (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; + vec3 ambient = pLambient[i];// * vec4(texture(material.diffuse, TexCoord)).xyz; + vec3 diffuse = pLdiffuse[i] * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz; + // vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz; ambient *= attenuation; diffuse *= attenuation; - specular *= attenuation; - return (ambient + diffuse + specular); -} + // specular *= attenuation; + vec3 specular = vec3(0,0,0); -// 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); + vec3 finalValue = (ambient + diffuse + specular); + finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0)); + + return finalValue; } diff --git a/assets/Shaders/flame1/flame.fs b/assets/Shaders/flame1/flame.fs new file mode 100644 index 00000000..aeaf5f1d --- /dev/null +++ b/assets/Shaders/flame1/flame.fs @@ -0,0 +1,213 @@ +/* +MIT License + +Copyright (c) 2022 railgunSR + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +*/ +/* +THIS MAKES USE OF OPENSIMPLEX2, A NOISE ALGORITHM CREATED BY THE FINE FOLKS +OVER AT https://github.com/KdotJPG/OpenSimplex2 +PLEASE GIVE THEM SOME LOVE. + +THE FLAME FUNCTION IS ONE CREATED BY ME BLENDING A LOG2 INTO A EXPONENTIAL. +*/ + +#version 330 core + +out vec4 fragColor; + +uniform float time; + +in vec3 FragPos; +in vec3 Normal; +in vec2 TexCoord; + +vec4 openSimplex2_ImproveXY(vec3 X); +float flameTex(float x, float y); + +void main(){ + + float timeS = time * 0.003; + + // Normalized pixel coordinates (from 0 to 1) + vec2 uv = vec2(TexCoord.x,1-TexCoord.y); + + // vec4 openVec = openSimplex2_ImproveXY(vec3(uv.x,uv.y,time)); + vec4 openVec = openSimplex2_ImproveXY(vec3(uv.x*3.0,uv.y*3.0 - timeS,0.0)); + + float nS = 3.0; //noise scale + + //compose textures + float flameXScale = 2.0; + float flameYScale = 2.0; + float flameVal = flameTex(uv.x*flameXScale-1.0/flameXScale,uv.y*flameYScale-1.0/flameYScale); + + float flameComp1 = flameVal * openSimplex2_ImproveXY(vec3(uv.x * nS ,uv.y * nS - timeS * 1.0,0.0)).x; + nS = 3.0; + float flameComp2 = flameVal * openSimplex2_ImproveXY(vec3(uv.x * nS ,uv.y * nS - timeS * 2.0,0.0)).x; + nS = 5.0; + float flameComp3 = flameVal * openSimplex2_ImproveXY(vec3(uv.x * nS + timeS * 1.0,uv.y * nS - timeS * 3.0,0.0)).x; + float flameComp4 = flameVal * openSimplex2_ImproveXY(vec3(uv.x * nS - timeS * 1.0,uv.y * nS - timeS * 3.0,0.0)).x; + nS = 3.0; + float flameComp5 = flameVal * openSimplex2_ImproveXY(vec3(uv.x * nS ,uv.y * nS - timeS * 1.5,0.0)).x; + float val = + flameVal * 3.0 + + flameComp1 * 0.2 + + flameComp2 * 0.2 + + flameComp3 * 0.2 + + flameComp4 * 0.2 + + flameComp5 * 0.2 + ; + + vec4 color = vec4( + min(val*2.0,1.0), + min(val*0.8,1.0), + min(val*0.2,1.0), + min(val,1.0) + ); + + if(val < 0.3){ + discard; + } + + // Output to screen + fragColor = color; +} + +// +//custom flame function +/// + +float flameTex(float x, float y){ + //flip y + float t = 1.0 - y; + //calculate vertical component + float verticalFlameValue = pow(log(t+1.0),1.4) - step(0.5,t) * (pow((2.0 * (t - 0.5)),3.0) / pow(log(2.0),1.4)); + //calculate dist along horizontal from vertical component + float dist = abs(x-0.5); + //want to fade to nothing at dist >= vertical flame value + //use exponent to get there + //clamp range with min + float v = max(2.0 * (verticalFlameValue - dist),0.0); + //apply exponent to get value + float rVal = pow(v,1.4); + return rVal; +} + + + +//////////////// K.jpg's Re-oriented 4-Point BCC Noise (OpenSimplex2) //////////////// +////////////////////// Output: vec4(dF/dx, dF/dy, dF/dz, value) ////////////////////// + +// Inspired by Stefan Gustavson's noise +vec4 permute(vec4 t) { + return t * (t * 34.0 + 133.0); +} + +// Gradient set is a normalized expanded rhombic dodecahedron +vec3 grad(float hash) { + + // Random vertex of a cube, +/- 1 each + vec3 cube = mod(floor(hash / vec3(1.0, 2.0, 4.0)), 2.0) * 2.0 - 1.0; + + // Random edge of the three edges connected to that vertex + // Also a cuboctahedral vertex + // And corresponds to the face of its dual, the rhombic dodecahedron + vec3 cuboct = cube; + cuboct[int(hash / 16.0)] = 0.0; + + // In a funky way, pick one of the four points on the rhombic face + float type = mod(floor(hash / 8.0), 2.0); + vec3 rhomb = (1.0 - type) * cube + type * (cuboct + cross(cube, cuboct)); + + // Expand it so that the new edges are the same length + // as the existing ones + vec3 grad = cuboct * 1.22474487139 + rhomb; + + // To make all gradients the same length, we only need to shorten the + // second type of vector. We also put in the whole noise scale constant. + // The compiler should reduce it into the existing floats. I think. + grad *= (1.0 - 0.042942436724648037 * type) * 32.80201376986577; + + return grad; +} + +// BCC lattice split up into 2 cube lattices +vec4 openSimplex2Base(vec3 X) { + + // First half-lattice, closest edge + vec3 v1 = round(X); + vec3 d1 = X - v1; + vec3 score1 = abs(d1); + vec3 dir1 = step(max(score1.yzx, score1.zxy), score1); + vec3 v2 = v1 + dir1 * sign(d1); + vec3 d2 = X - v2; + + // Second half-lattice, closest edge + vec3 X2 = X + 144.5; + vec3 v3 = round(X2); + vec3 d3 = X2 - v3; + vec3 score2 = abs(d3); + vec3 dir2 = step(max(score2.yzx, score2.zxy), score2); + vec3 v4 = v3 + dir2 * sign(d3); + vec3 d4 = X2 - v4; + + // Gradient hashes for the four points, two from each half-lattice + vec4 hashes = permute(mod(vec4(v1.x, v2.x, v3.x, v4.x), 289.0)); + hashes = permute(mod(hashes + vec4(v1.y, v2.y, v3.y, v4.y), 289.0)); + hashes = mod(permute(mod(hashes + vec4(v1.z, v2.z, v3.z, v4.z), 289.0)), 48.0); + + // Gradient extrapolations & kernel function + vec4 a = max(0.5 - vec4(dot(d1, d1), dot(d2, d2), dot(d3, d3), dot(d4, d4)), 0.0); + vec4 aa = a * a; vec4 aaaa = aa * aa; + vec3 g1 = grad(hashes.x); vec3 g2 = grad(hashes.y); + vec3 g3 = grad(hashes.z); vec3 g4 = grad(hashes.w); + vec4 extrapolations = vec4(dot(d1, g1), dot(d2, g2), dot(d3, g3), dot(d4, g4)); + + // Derivatives of the noise + vec3 derivative = -8.0 * mat4x3(d1, d2, d3, d4) * (aa * a * extrapolations) + + mat4x3(g1, g2, g3, g4) * aaaa; + + // Return it all as a vec4 + return vec4(derivative, dot(aaaa, extrapolations)); +} + +// Use this if you don't want Z to look different from X and Y +vec4 openSimplex2_Conventional(vec3 X) { + + // Rotate around the main diagonal. Not a skew transform. + vec4 result = openSimplex2Base(dot(X, vec3(2.0/3.0)) - X); + return vec4(dot(result.xyz, vec3(2.0/3.0)) - result.xyz, result.w); +} + +// Use this if you want to show X and Y in a plane, then use Z for time, vertical, etc. +vec4 openSimplex2_ImproveXY(vec3 X) { + + // Rotate so Z points down the main diagonal. Not a skew transform. + mat3 orthonormalMap = mat3( + 0.788675134594813, -0.211324865405187, -0.577350269189626, + -0.211324865405187, 0.788675134594813, -0.577350269189626, + 0.577350269189626, 0.577350269189626, 0.577350269189626); + + vec4 result = openSimplex2Base(orthonormalMap * X); + return vec4(result.xyz * orthonormalMap, result.w); +} + +//////////////////////////////// End noise code //////////////////////////////// \ No newline at end of file diff --git a/assets/Shaders/flame1/flame.vs b/assets/Shaders/flame1/flame.vs new file mode 100644 index 00000000..cb78b1de --- /dev/null +++ b/assets/Shaders/flame1/flame.vs @@ -0,0 +1,45 @@ +//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 float time; + + + +//output buffers +out vec3 Normal; +out vec3 FragPos; +out vec2 TexCoord; + + + + +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; + + + + + //set final position with opengl space + gl_Position = projection * view * model * FinalVertex; +} diff --git a/assets/Shaders/terrain/terrain.fs b/assets/Shaders/terrain/terrain.fs index 85aae85e..9a1ed971 100644 --- a/assets/Shaders/terrain/terrain.fs +++ b/assets/Shaders/terrain/terrain.fs @@ -1,61 +1,53 @@ - - #version 410 core +#extension GL_ARB_explicit_uniform_location : enable + +#define NR_POINT_LIGHTS 10 + + out vec4 FragColor; + +layout (std140) uniform Lights { + // this is how many because we have to align + // bytes it SHOULD in multiples of 16, this + // take it where it ACTUALLY is + // + //refer: https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL + // + // base alignment aligned offset + //direct light + vec3 dLDirection; // 16 0 + vec3 dLAmbient; // 16 16 + vec3 dLDiffuse; // 16 32 + vec3 dLSpecular; // 16 48 + + //point light + vec3 pLposition[NR_POINT_LIGHTS]; // 16*10 64 + float pLconstant[NR_POINT_LIGHTS]; // 16*10 224 + float pLlinear[NR_POINT_LIGHTS]; // 16*10 384 + float pLquadratic[NR_POINT_LIGHTS]; // 16*10 544 + vec3 pLambient[NR_POINT_LIGHTS]; // 16*10 704 + vec3 pLdiffuse[NR_POINT_LIGHTS]; // 16*10 864 + vec3 pLspecular[NR_POINT_LIGHTS]; // 16*10 1024 + + //for a total size of 1184 + +}; + 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; flat in ivec4 groundTexIndices; - uniform vec3 viewPos; -uniform DirLight dirLight; -uniform PointLight pointLights[NR_POINT_LIGHTS]; -uniform SpotLight spotLight; + + uniform Material material; //texture stuff @@ -64,7 +56,7 @@ uniform int hasTransparency; // uniform sampler2D specularTexture; //light depth map -uniform sampler2D shadowMap; +layout (location = 3) uniform sampler2D shadowMap; //textures // @@ -79,14 +71,19 @@ uniform sampler2D shadowMap; // //fifth texture unit is for shadow map // uniform sampler2D groundTextures5; //this is for bindable ground textures -uniform sampler2D groundTextures[10]; +layout (location = 5) uniform sampler2D groundTextures[10]; // function prototypes -vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir, vec3 texColor); -vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir); -vec3 CalcSpotLight(SpotLight light, vec3 normal, vec3 fragPos, vec3 viewDir); +vec3 CalcDirLight(vec3 normal, vec3 viewDir, vec3 texColor); +vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir); +// vec3 CalcSpotLight(vec3 normal, vec3 fragPos, vec3 viewDir); + float ShadowCalculation(vec4 fragPosLightSpace, vec3 lightDir, vec3 normal); + vec3 blendedTextureColor(vec2 texPos, vec4 tex1, vec4 tex2, vec4 tex3, vec4 tex4); + + + vec4 getTextureColor(int index, vec2 coord){ if(index == 0){ return texture(groundTextures[0], coord); @@ -104,7 +101,7 @@ vec4 getTextureColor(int index, vec2 coord){ return texture(groundTextures[4], coord); } // return vec3(1,1,1); - return vec4(0,0,0,0); + return vec4(0,0,0,1); } void main(){ @@ -150,18 +147,18 @@ void main(){ // vec3 texColor = vec3(0,0,1);//blendedTextureColor(texPos, groundTexIndices); - vec3 result = CalcDirLight(dirLight, norm, viewDir, finalTexColor); - //for(int i = 0; i < NR_POINT_LIGHTS; i++){ - // result += CalcPointLight(pointLights[i], norm, FragPos, viewDir); - //} - //result += CalcSpotLight(spotLight, norm, FragPos, viewDir); + vec3 result = CalcDirLight(norm, viewDir, finalTexColor); + for(int i = 0; i < NR_POINT_LIGHTS; i++){ + result += CalcPointLight(i, norm, FragPos, viewDir); + } + // result += CalcSpotLight(spotLight, norm, FragPos, viewDir); FragColor = vec4(result, 1);//texture(ourTexture, TexCoord);//vec4(result, 1.0); } // calculates the color when using a directional light. -vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir, vec3 texColor){ - vec3 lightDir = normalize(-light.direction); +vec3 CalcDirLight(vec3 normal, vec3 viewDir, vec3 texColor){ + vec3 lightDir = normalize(-dLDirection); // diffuse shading float diff = max(dot(normal, lightDir), 0.0); // specular shading @@ -169,8 +166,8 @@ vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir, vec3 texColor){ 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 ambient = dLAmbient; + vec3 diffuse = dLDiffuse * diff; //vec3 specular = light.specular * spec * vec3(texture(material.specular, TexCoord).rgb); @@ -181,51 +178,56 @@ vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir, vec3 texColor){ // calculates the color when using a point light. -vec3 CalcPointLight(PointLight light, vec3 normal, vec3 fragPos, vec3 viewDir){ - vec3 lightDir = normalize(light.position - fragPos); +vec3 CalcPointLight(int i, vec3 normal, vec3 fragPos, vec3 viewDir){ + vec3 lightDir = normalize(pLposition[i] - 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); + // 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)); + float distance = length(pLposition[i] - fragPos); + float attenuation = 1.0 / (pLconstant[i] + pLlinear[i] * distance + pLquadratic[i] * (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; + vec3 ambient = pLambient[i];// * vec4(texture(material.diffuse, TexCoord)).xyz; + vec3 diffuse = pLdiffuse[i] * diff;// * vec4(texture(material.diffuse, TexCoord)).xyz; + // vec3 specular = pLspecular[i] * spec;// * vec4(texture(material.specular, TexCoord)).xyz; ambient *= attenuation; diffuse *= attenuation; - specular *= attenuation; - return (ambient + diffuse + specular); + // specular *= attenuation; + vec3 specular = vec3(0,0,0); + + vec3 finalValue = (ambient + diffuse + specular); + finalValue = vec3(max(finalValue.x,0),max(finalValue.y,0),max(finalValue.z,0)); + + return finalValue; } // 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); -} +// vec3 CalcSpotLight(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){ diff --git a/assets/Shaders/terrain/terrain.fs.bak b/assets/Shaders/terrain/terrain.fs.bak deleted file mode 100644 index e1173905..00000000 --- a/assets/Shaders/terrain/terrain.fs.bak +++ /dev/null @@ -1,220 +0,0 @@ - - -#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; -in ivec4 groundTexIndices; - -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; - -//textures -// -// Goal is to have a texture for the current chunk and one for each nearnby chunk -// -// -// -// uniform sampler2D groundTextures[10]; - - -// 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); -vec3 blendedTextureColor(vec2 texPos, ivec4 groundTexIndex); - -void main(){ - if(hasTransparency == 1){ - if(texture(material.diffuse, TexCoord).a < 0.1){ - discard; - } - } - vec3 norm = normalize(Normal); - vec3 viewDir = normalize(viewPos - FragPos); - - //get texture color - vec3 texColor = vec3(0,0,1);//blendedTextureColor(texPos, groundTexIndices); - - - 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); - // FragColor = vec4(result, 1);//texture(ourTexture, TexCoord);//vec4(result, 1.0); -} - -// calculates the color when using a directional light. -vec3 CalcDirLight(DirLight light, vec3 normal, vec3 viewDir, vec3 texColor){ - // //get texture color - // vec3 texColor = vec3(1,0,0);//blendedTextureColor(texPos, groundTexIndices); - //get light direction - 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) * diffuse ) * 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; -} - - -// vec3 blendedTextureColor(vec2 texPos, ivec4 groundTexIndex){ -// vec4 tex1 = texture2D(groundTextures[groundTexIndex.x * 2], texPos); -// vec4 tex2 = texture2D(groundTextures[groundTexIndex.y * 2], texPos); -// vec4 tex3 = texture2D(groundTextures[groundTexIndex.z * 2], texPos); -// vec4 tex4 = texture2D(groundTextures[groundTexIndex.w * 2], texPos); -// // float percentTex1 = (texPos.x - 1) * (texPos.y - 1); -// // float percentTex2 = (texPos.x - 0) * (texPos.y - 1); -// // float percentTex3 = (texPos.x - 1) * (texPos.y - 0); -// // float percentTex4 = (texPos.x - 0) * (texPos.y - 0); -// return mix(mix(tex1,tex2,texPos.x),mix(tex3,tex4,texPos.x),texPos.y).rgb; -// } \ No newline at end of file diff --git a/assets/Shaders/terrain/terrain.vs b/assets/Shaders/terrain/terrain.vs index ac0a4332..a969fe26 100644 --- a/assets/Shaders/terrain/terrain.vs +++ b/assets/Shaders/terrain/terrain.vs @@ -15,7 +15,6 @@ uniform mat4 transform; uniform mat4 model; uniform mat4 view; uniform mat4 projection; -uniform mat4 lightSpaceMatrix; @@ -23,7 +22,6 @@ uniform mat4 lightSpaceMatrix; out vec3 Normal; out vec3 FragPos; out vec2 TexCoord; -out vec4 FragPosLightSpace; flat out ivec4 groundTexIndices; @@ -37,17 +35,13 @@ void main() { //push frag, normal, and texture positions to fragment shader FragPos = vec3(model * FinalVertex); - Normal = mat3(transpose(inverse(model))) * aNormal; + Normal = mat3(transpose(inverse(model))) * FinalNormal.xyz; TexCoord = aTex; //push texure indices to fragment shader groundTexIndices = ivec4(int(aGroundTexIndices.x),int(aGroundTexIndices.y),int(aGroundTexIndices.z),int(aGroundTexIndices.w)); // groundTexIndices = vec4(int(aGroundTexIndices.x),int(aGroundTexIndices.y),int(aGroundTexIndices.z),int(aGroundTexIndices.w)); // groundTexIndices = ivec4(0,1,2,3); - - //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/campfire1.png b/assets/Textures/campfire1.png new file mode 100644 index 00000000..49087372 Binary files /dev/null and b/assets/Textures/campfire1.png differ diff --git a/assets/Textures/default_texture_map.json b/assets/Textures/default_texture_map.json index 1f18263a..4e98ad67 100644 --- a/assets/Textures/default_texture_map.json +++ b/assets/Textures/default_texture_map.json @@ -251,6 +251,12 @@ "/Textures/starrySky.png", "/Textures/starrySky.png" ] + }, + "Models/campfire1.fbx" : { + "Cylinder" : [ + "/Textures/campfire1.png", + "/Textures/campfire1.png" + ] } } } \ No newline at end of file diff --git a/src/main/java/electrosphere/engine/LoadingThread.java b/src/main/java/electrosphere/engine/LoadingThread.java index a43024d0..e978443f 100644 --- a/src/main/java/electrosphere/engine/LoadingThread.java +++ b/src/main/java/electrosphere/engine/LoadingThread.java @@ -42,6 +42,7 @@ import electrosphere.net.client.ClientNetworking; import electrosphere.net.server.Server; import electrosphere.renderer.Model; import electrosphere.renderer.RenderUtils; +import electrosphere.renderer.actor.Actor; import electrosphere.renderer.actor.ActorUtils; import electrosphere.engine.assetmanager.AssetDataStrings; import electrosphere.game.client.targeting.crosshair.Crosshair; @@ -671,6 +672,43 @@ public class LoadingThread extends Thread { Entity hair = ItemUtils.spawnBasicItem("hairshort1"); EntityUtils.getPosition(hair).set(new Vector3f(2,0.1f,1)); + //center flame + Entity fire = ParticleUtils.spawnStaticBillboardParticle(); + EntityUtils.getPosition(fire).set(new Vector3f(1,0.2f,1)); + EntityUtils.getScale(fire).set(0.6f); + Actor fireActor = EntityUtils.getActor(fire); + fireActor.maskShader("particleBillboard", "Shaders/flame1/flame.vs", "Shaders/flame1/flame.fs"); + Globals.assetManager.addShaderToQueue("Shaders/flame1/flame.vs", "Shaders/flame1/flame.fs"); + //corner flame 1 + fire = ParticleUtils.spawnStaticBillboardParticle(); + EntityUtils.getPosition(fire).set(new Vector3f(1.05f,0.1f,0.95f)); + EntityUtils.getScale(fire).set(0.4f); + fireActor = EntityUtils.getActor(fire); + fireActor.maskShader("particleBillboard", "Shaders/flame1/flame.vs", "Shaders/flame1/flame.fs"); + //corner flame 2 + fire = ParticleUtils.spawnStaticBillboardParticle(); + EntityUtils.getPosition(fire).set(new Vector3f(1.05f,0.1f,1.05f)); + EntityUtils.getScale(fire).set(0.4f); + fireActor = EntityUtils.getActor(fire); + fireActor.maskShader("particleBillboard", "Shaders/flame1/flame.vs", "Shaders/flame1/flame.fs"); + //corner flame 3 + fire = ParticleUtils.spawnStaticBillboardParticle(); + EntityUtils.getPosition(fire).set(new Vector3f(0.95f,0.1f,0.95f)); + EntityUtils.getScale(fire).set(0.4f); + fireActor = EntityUtils.getActor(fire); + fireActor.maskShader("particleBillboard", "Shaders/flame1/flame.vs", "Shaders/flame1/flame.fs"); + //corner flame 4 + fire = ParticleUtils.spawnStaticBillboardParticle(); + EntityUtils.getPosition(fire).set(new Vector3f(0.95f,0.1f,1.05f)); + EntityUtils.getScale(fire).set(0.4f); + fireActor = EntityUtils.getActor(fire); + fireActor.maskShader("particleBillboard", "Shaders/flame1/flame.vs", "Shaders/flame1/flame.fs"); + + //campfire + Entity campfire = EntityUtils.spawnDrawableEntity("Models/campfire1.fbx"); + EntityUtils.getPosition(campfire).set(1,0,1); + EntityUtils.getRotation(campfire).rotationX(-(float)Math.PI/2.0f); + // goblin = CreatureUtils.spawnBasicCreature("Goblin"); // CollisionObjUtils.positionCharacter(goblin, new Vector3f(3, 0, 4)); // EntityUtils.getScale(goblin).set(0.005f); diff --git a/src/main/java/electrosphere/engine/assetmanager/AssetManager.java b/src/main/java/electrosphere/engine/assetmanager/AssetManager.java index 44d89f43..577549be 100644 --- a/src/main/java/electrosphere/engine/assetmanager/AssetManager.java +++ b/src/main/java/electrosphere/engine/assetmanager/AssetManager.java @@ -4,6 +4,7 @@ import electrosphere.audio.AudioBuffer; import electrosphere.renderer.Mesh; import electrosphere.renderer.Model; import electrosphere.renderer.ShaderProgram; +import electrosphere.renderer.actor.ActorShaderMask; import electrosphere.renderer.texture.Texture; import electrosphere.util.ModelLoader; @@ -29,6 +30,10 @@ public class AssetManager { Map audioLoadedIntoMemory = new ConcurrentHashMap(); List audioInQueue = new CopyOnWriteArrayList(); + + Map shadersLoadedIntoMemory = new ConcurrentHashMap(); + List shadersInQueue = new CopyOnWriteArrayList(); + @@ -52,6 +57,13 @@ public class AssetManager { audioInQueue.remove(currentPath); audioLoadedIntoMemory.put(currentPath, new AudioBuffer(currentPath)); } + for(ActorShaderMask currentShader : shadersInQueue){ + shadersInQueue.remove(currentShader); + shadersLoadedIntoMemory.put( + getShaderKey(currentShader.getVertexShaderPath(),currentShader.getFragmentShaderPath()), + ShaderProgram.loadSpecificShader(currentShader.getVertexShaderPath(),currentShader.getFragmentShaderPath()) + ); + } performMeshOverrides(); } @@ -192,7 +204,31 @@ public class AssetManager { } - + + + + + + + // + //SHADERS + // + public void addShaderToQueue(String vertexShader, String fragmentShader){ + shadersInQueue.add(new ActorShaderMask("","",vertexShader,fragmentShader)); + } + + public ShaderProgram fetchShader(String vertexPath, String fragmentPath){ + String path = getShaderKey(vertexPath,fragmentPath); + ShaderProgram rVal = null; + if(shadersLoadedIntoMemory.containsKey(path)){ + rVal = shadersLoadedIntoMemory.get(path); + } + return rVal; + } + + static String getShaderKey(String vertexPath, String fragmentPath){ + return vertexPath + "-" + fragmentPath; + } diff --git a/src/main/java/electrosphere/entity/state/ParticleTree.java b/src/main/java/electrosphere/entity/state/ParticleTree.java index 443c95b1..0ab02fda 100644 --- a/src/main/java/electrosphere/entity/state/ParticleTree.java +++ b/src/main/java/electrosphere/entity/state/ParticleTree.java @@ -12,18 +12,20 @@ import org.joml.Vector3f; */ public class ParticleTree { Entity parent; + boolean hasLife = true; int maxLife; int lifeCurrent; Vector3f destination; float velocity; float acceleration; - public ParticleTree(Entity parent, int maxLife, Vector3f destination, float velocity, float acceleration){ + public ParticleTree(Entity parent, int maxLife, Vector3f destination, float velocity, float acceleration, boolean hasLife){ this.parent = parent; this.maxLife = maxLife; this.destination = destination; this.velocity = velocity; this.acceleration = acceleration; + this.hasLife = hasLife; lifeCurrent = maxLife; } @@ -55,9 +57,11 @@ public class ParticleTree { velocity = 0; acceleration = 0; } - lifeCurrent--; - if(lifeCurrent <= 0){ - Globals.entityManager.deregisterEntity(parent); + if(hasLife){ + lifeCurrent--; + if(lifeCurrent <= 0){ + Globals.entityManager.deregisterEntity(parent); + } } } diff --git a/src/main/java/electrosphere/entity/types/particle/ParticleUtils.java b/src/main/java/electrosphere/entity/types/particle/ParticleUtils.java index ece0c730..fb5e118e 100644 --- a/src/main/java/electrosphere/entity/types/particle/ParticleUtils.java +++ b/src/main/java/electrosphere/entity/types/particle/ParticleUtils.java @@ -20,11 +20,20 @@ public class ParticleUtils { - public static Entity spawnBillboardParticle(String texture, int maxLife, Vector3f destination, float velocity, float acceleration){ + public static Entity spawnBillboardProjectileParticle(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); + ParticleTree particleTree = new ParticleTree(rVal, maxLife, destination, velocity, acceleration, true); + rVal.putData(EntityDataStrings.PARTICLE_TREE, particleTree); + rVal.putData(EntityDataStrings.IS_PARTICLE, true); + Globals.entityManager.registerParticle(rVal); + return rVal; + } + + public static Entity spawnStaticBillboardParticle(){ + Entity rVal = EntityUtils.spawnDrawableEntity(Globals.particleBillboardModel); + ParticleTree particleTree = new ParticleTree(rVal, 10, new Vector3f(0,0,0), 0, 0, false); rVal.putData(EntityDataStrings.PARTICLE_TREE, particleTree); rVal.putData(EntityDataStrings.IS_PARTICLE, true); Globals.entityManager.registerParticle(rVal); diff --git a/src/main/java/electrosphere/game/server/effects/ParticleEffects.java b/src/main/java/electrosphere/game/server/effects/ParticleEffects.java index cd7d40bc..e9fb814a 100644 --- a/src/main/java/electrosphere/game/server/effects/ParticleEffects.java +++ b/src/main/java/electrosphere/game/server/effects/ParticleEffects.java @@ -20,7 +20,7 @@ public class ParticleEffects { 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.spawnBillboardParticle("Textures/spark1.png", 15, direction, velocity, acceleration); + Entity spark = ParticleUtils.spawnBillboardProjectileParticle("Textures/spark1.png", 15, direction, velocity, acceleration); EntityUtils.getPosition(spark).set(position); EntityUtils.getScale(spark).mul(0.03f); } @@ -33,7 +33,7 @@ public class ParticleEffects { Vector3f direction = new Vector3f(rand.nextFloat() - 0.5f,rand.nextFloat() - 0.5f,rand.nextFloat() - 0.5f).normalize(); float velocity = rand.nextFloat() * 0.001f; float acceleration = 0.000005f; - Entity spark = ParticleUtils.spawnBillboardParticle("Textures/bloodsplat1.png", 90, direction, velocity, acceleration); + Entity spark = ParticleUtils.spawnBillboardProjectileParticle("Textures/bloodsplat1.png", 90, direction, velocity, acceleration); EntityUtils.getPosition(spark).set(position); EntityUtils.getScale(spark).mul(0.1f); } diff --git a/src/main/java/electrosphere/renderer/Mesh.java b/src/main/java/electrosphere/renderer/Mesh.java index 257c924c..32931df7 100644 --- a/src/main/java/electrosphere/renderer/Mesh.java +++ b/src/main/java/electrosphere/renderer/Mesh.java @@ -4,7 +4,7 @@ import electrosphere.entity.types.camera.CameraEntityUtils; import electrosphere.logger.LoggerInterface; import electrosphere.main.Globals; import electrosphere.main.Main; -import electrosphere.renderer.light.LightBuffer; +import electrosphere.renderer.light.LightManager; import electrosphere.renderer.texture.Texture; import java.nio.FloatBuffer; import java.nio.IntBuffer; @@ -98,8 +98,6 @@ public class Mesh { Material material; - LightBuffer light_buffer; - public static Mesh create_mesh_from_aimesh(AIMesh mesh){ boolean has_bones = false; boolean apply_lighting = true; @@ -732,7 +730,7 @@ public class Mesh { 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){ + if(Globals.renderingEngine.getLightManager() == null){ //this needs to get transformed by the view matrix and isn't Vector3f lightLoc = new Vector3f(0.2f,-1.0f,0.3f); @@ -760,7 +758,7 @@ public class Mesh { 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])); + // GL20.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "model"), false, parent.modelMatrix.get(new float[16])); //set in standard uniforms // @@ -770,7 +768,9 @@ public class Mesh { // 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])); + LightManager lightManager = Globals.renderingEngine.getLightManager(); + lightManager.bindBuffer(Globals.renderingEngine.getActiveShader().shaderProgram); + // GL20.glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "model"), false, parent.modelMatrix.get(new float[16])); } } @@ -810,9 +810,9 @@ public class Mesh { glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "groundTextures[" + i + "]"),5+i); i++; } - for(int j = i; j < 10; j++){ - glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "groundTextures[" + j + "]"),5+j); - } + // for(int j = i; j < 10; j++){ + // glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "groundTextures[" + j + "]"),6+j); + // } // glActiveTexture(GL_TEXTURE0); } @@ -870,6 +870,7 @@ public class Mesh { glUniform3fv(Globals.renderingEngine.getActiveShader().shaderVertexViewPosLoc, CameraEntityUtils.getCameraEye(Globals.playerCamera).get(BufferUtils.createFloatBuffer(3))); glUniformMatrix4fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "lightSpaceMatrix"), false, Globals.lightDepthMatrix.get(new float[16])); glUniform1i(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "frame"), (int)Main.frameCount); + glUniform1f(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "time"), (float)Main.frameCount); } if(bufferNonStandardUniforms){ diff --git a/src/main/java/electrosphere/renderer/Model.java b/src/main/java/electrosphere/renderer/Model.java index cdd5b342..d5f5297f 100644 --- a/src/main/java/electrosphere/renderer/Model.java +++ b/src/main/java/electrosphere/renderer/Model.java @@ -2,6 +2,7 @@ package electrosphere.renderer; import electrosphere.renderer.actor.ActorAnimationMask; import electrosphere.renderer.actor.ActorMeshMask; +import electrosphere.renderer.actor.ActorShaderMask; import electrosphere.renderer.anim.AnimChannel; import electrosphere.renderer.anim.Animation; import electrosphere.renderer.anim.AnimNode; @@ -59,6 +60,7 @@ public class Model { AnimNode root_anim_node; ActorMeshMask meshMask; + Map shaderMask = new HashMap(); public static Model createModelFromAiscene(AIScene s){ Model rVal = new Model(); @@ -201,15 +203,36 @@ public class Model { while(mesh_Iterator.hasNext()){ Mesh currentMesh = mesh_Iterator.next(); if(!meshMask.isBlockedMesh(currentMesh.nodeID)){ + ShaderProgram original = currentMesh.shader; + ShaderProgram shader = getCorrectShader(shaderMask, currentMesh, currentMesh.shader); + currentMesh.shader = shader; currentMesh.complexDraw(setShader, bufferStandardUniforms, bufferNonStandardUniforms, useMaterial, useShadowMap, setBones, useLight); + currentMesh.shader = original; } } for(Mesh toDraw : meshMask.getToDrawMeshes()){ toDraw.bones = bones; toDraw.parent = this; + ShaderProgram original = toDraw.shader; + ShaderProgram shader = getCorrectShader(shaderMask, toDraw, toDraw.shader); + toDraw.shader = shader; toDraw.complexDraw(setShader, bufferStandardUniforms, bufferNonStandardUniforms, useMaterial, useShadowMap, setBones, useLight); + toDraw.shader = original; } } + + ShaderProgram getCorrectShader(Map shaderMask, Mesh mesh, ShaderProgram oldShader){ + ShaderProgram rVal = oldShader; + if(shaderMask.containsKey(mesh.nodeID)){ + ActorShaderMask specificMask = shaderMask.get(mesh.nodeID); + ShaderProgram overwriteShader = null; + if((overwriteShader = Globals.assetManager.fetchShader(specificMask.getVertexShaderPath(), specificMask.getFragmentShaderPath())) != null){ + ShaderProgram oldProgram = mesh.shader; + rVal = overwriteShader; + } + } + return rVal; + } // public void playAnimation(String s){ @@ -437,6 +460,10 @@ public class Model { public Animation getAnimation(String animName){ return animMap.get(animName); } + + public Map getShaderMask(){ + return shaderMask; + } public void describeHighLevel(){ System.out.println("Meshes: "); diff --git a/src/main/java/electrosphere/renderer/RenderUtils.java b/src/main/java/electrosphere/renderer/RenderUtils.java index d9fabd86..33150f28 100644 --- a/src/main/java/electrosphere/renderer/RenderUtils.java +++ b/src/main/java/electrosphere/renderer/RenderUtils.java @@ -1016,6 +1016,7 @@ public class RenderUtils { Model rVal = new Model(); rVal.meshes = new ArrayList(); Mesh m = new Mesh(); + m.nodeID = "terrain"; int width = heightfield.length; int height = heightfield[0].length; @@ -1508,7 +1509,7 @@ public class RenderUtils { // } // } - System.out.println(incrementer + " quads"); + // System.out.println(incrementer + " quads"); vertices.flip(); normals.flip(); diff --git a/src/main/java/electrosphere/renderer/RenderingEngine.java b/src/main/java/electrosphere/renderer/RenderingEngine.java index 1f0a3e8a..4f1b68e2 100644 --- a/src/main/java/electrosphere/renderer/RenderingEngine.java +++ b/src/main/java/electrosphere/renderer/RenderingEngine.java @@ -22,6 +22,7 @@ import electrosphere.renderer.actor.Actor; import electrosphere.renderer.framebuffer.Framebuffer; import electrosphere.renderer.framebuffer.FramebufferUtils; import electrosphere.renderer.framebuffer.Renderbuffer; +import electrosphere.renderer.light.LightManager; import electrosphere.renderer.texture.Texture; import electrosphere.renderer.ui.DrawableElement; import electrosphere.renderer.ui.Element; @@ -114,6 +115,8 @@ public class RenderingEngine { // public static boolean renderHitboxes = false; // public static boolean renderPhysics = false; + + LightManager lightManager; static float currentViewPlanarAngle; @@ -213,6 +216,11 @@ public class RenderingEngine { lightDepthBuffer = FramebufferUtils.generateDepthBuffer(); Globals.shadowMapTextureLoc = lightDepthBuffer.getTexturePointer(); // glEnable(GL_CULL_FACE); // enabled for shadow mapping + + + + //instantiate light manager + lightManager = new LightManager(); // //Fog @@ -295,6 +303,10 @@ public class RenderingEngine { renderShadowMapContent(); } + /* + Update light buffer + */ + lightManager.updateData(); /* Render content to the game framebuffer @@ -755,5 +767,9 @@ public class RenderingEngine { Globals.WINDOW_TITLE_BAR_HEIGHT = tTop.get(); // System.out.println(tLeft.get() + " " + tTop.get() + " " + tRight.get() + " " + tBottom.get()); } + + public LightManager getLightManager(){ + return lightManager; + } } diff --git a/src/main/java/electrosphere/renderer/ShaderProgram.java b/src/main/java/electrosphere/renderer/ShaderProgram.java index 3ed1f847..1d47ebee 100644 --- a/src/main/java/electrosphere/renderer/ShaderProgram.java +++ b/src/main/java/electrosphere/renderer/ShaderProgram.java @@ -284,16 +284,14 @@ public class ShaderProgram { public static ShaderProgram loadSpecificShader(String vertexPath, String fragmentPath){ ShaderProgram rVal = new ShaderProgram(); - String vertex_shader_path = vertexPath; - String fragment_shader_path = fragmentPath; // //Read in shader programs // String vertexShaderSource = ""; String fragmentShaderSource = ""; try { - vertexShaderSource = FileUtils.getAssetFileAsString(vertex_shader_path); - fragmentShaderSource = FileUtils.getAssetFileAsString(fragment_shader_path); + vertexShaderSource = FileUtils.getAssetFileAsString(vertexPath); + fragmentShaderSource = FileUtils.getAssetFileAsString(fragmentPath); } catch(IOException ex){ } diff --git a/src/main/java/electrosphere/renderer/actor/Actor.java b/src/main/java/electrosphere/renderer/actor/Actor.java index ffda9ff5..e9c63212 100644 --- a/src/main/java/electrosphere/renderer/actor/Actor.java +++ b/src/main/java/electrosphere/renderer/actor/Actor.java @@ -1,4 +1,4 @@ - package electrosphere.renderer.actor; +package electrosphere.renderer.actor; import electrosphere.main.Globals; import electrosphere.renderer.Bone; @@ -25,6 +25,7 @@ public class Actor { float animationScalar = 1.0f; PriorityQueue animationQueue = new PriorityQueue(); ActorMeshMask meshMask = new ActorMeshMask(); + List shaderMasks = new LinkedList(); public Actor(String modelPath){ this.modelPath = modelPath; @@ -192,6 +193,11 @@ public class Actor { // playingAnimation = false; // } // } + for(ActorShaderMask shaderMask : shaderMasks){ + if(shaderMask.getModelName().equals(modelPath)){ + model.getShaderMask().put(shaderMask.getMeshName(),shaderMask); + } + } if(textureOverride != null){ Texture overrideTextureObject = Globals.assetManager.fetchTexture(textureOverride); if(overrideTextureObject != null){ @@ -203,6 +209,7 @@ public class Actor { if(!hasDrawn){ model.draw(true, true, false, true, true, true, true); } + model.getShaderMask().clear(); } } @@ -313,5 +320,13 @@ public class Actor { return meshMask; } + public void maskShader(String mesh, String vertexShader, String fragmentShader){ + shaderMasks.add(new ActorShaderMask(this.modelPath, mesh, vertexShader, fragmentShader)); + } + + public void unmaskShader(String mesh){ + throw new UnsupportedOperationException("Not implemented yet"); + } + } diff --git a/src/main/java/electrosphere/renderer/actor/ActorShaderMask.java b/src/main/java/electrosphere/renderer/actor/ActorShaderMask.java new file mode 100644 index 00000000..4a36f85a --- /dev/null +++ b/src/main/java/electrosphere/renderer/actor/ActorShaderMask.java @@ -0,0 +1,33 @@ +package electrosphere.renderer.actor; + +public class ActorShaderMask { + + String modelName; + String meshName; + String vertexShaderPath; + String fragmentShaderPath; + + public ActorShaderMask(String modelName, String meshName, String vertexShaderPath, String fragmentShaderPath){ + this.modelName = modelName; + this.meshName = meshName; + this.vertexShaderPath = vertexShaderPath; + this.fragmentShaderPath = fragmentShaderPath; + } + + public String getModelName(){ + return modelName; + } + + public String getMeshName(){ + return meshName; + } + + public String getVertexShaderPath(){ + return vertexShaderPath; + } + + public String getFragmentShaderPath(){ + return fragmentShaderPath; + } + +} diff --git a/src/main/java/electrosphere/renderer/light/LightBuffer.java b/src/main/java/electrosphere/renderer/light/LightBuffer.java deleted file mode 100644 index e95e4d70..00000000 --- a/src/main/java/electrosphere/renderer/light/LightBuffer.java +++ /dev/null @@ -1,18 +0,0 @@ -package electrosphere.renderer.light; - -import static org.lwjgl.opengl.GL15.*; -import static org.lwjgl.opengl.GL31.GL_UNIFORM_BUFFER; - -/** - * - * @author amaterasu - */ -public class LightBuffer { - int light_uniform_buffer_address; - - public LightBuffer(){ - light_uniform_buffer_address = glGenBuffers(); - glBindBuffer(GL_UNIFORM_BUFFER,light_uniform_buffer_address); - //glBufferData(GL_UNIFORM_BUFFER, , GL_STATIC_DRAW); - } -} \ No newline at end of file diff --git a/src/main/java/electrosphere/renderer/light/LightManager.java b/src/main/java/electrosphere/renderer/light/LightManager.java index d59b7fc9..4cba4b3d 100644 --- a/src/main/java/electrosphere/renderer/light/LightManager.java +++ b/src/main/java/electrosphere/renderer/light/LightManager.java @@ -1,6 +1,17 @@ package electrosphere.renderer.light; -import java.util.List; +import static org.lwjgl.opengl.GL15.*; +import static org.lwjgl.opengl.GL31.GL_UNIFORM_BUFFER; + +import java.nio.ByteBuffer; + +import org.joml.Vector3f; +import org.lwjgl.BufferUtils; +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.GL31; + +import electrosphere.entity.types.camera.CameraEntityUtils; +import electrosphere.main.Globals; /** * @@ -8,4 +19,212 @@ import java.util.List; */ public class LightManager { + final static int BIND_POINT = 1; + final static int POINT_LIGHT_COUNT = 10; + final static int BUFFER_SIZE = 1184; + int uboIndex; + ByteBuffer dataBuffer; + + //sun position (For shadow maps) + Vector3f sunPosition = new Vector3f(0.2f,-1.0f,0.3f); + + //lights + DirectionalLight directionalLight; + PointLight[] pointLights; + + public LightManager(){ + + //create data buffer + dataBuffer = BufferUtils.createByteBuffer(BUFFER_SIZE); + + uboIndex = glGenBuffers(); + glBindBuffer(GL_UNIFORM_BUFFER, uboIndex); + glBufferData(GL_UNIFORM_BUFFER, BUFFER_SIZE, GL_DYNAMIC_DRAW); // allocate 152 bytes of memory + //set range to full size + int offset = 0; + GL30.glBindBufferRange(GL_UNIFORM_BUFFER, BIND_POINT, uboIndex, offset, BUFFER_SIZE); + //unbind + glBindBuffer(GL_UNIFORM_BUFFER, 0); + + //create directional light + directionalLight = new DirectionalLight(new Vector3f(1,-1,0).normalize()); + directionalLight.setAmbient(new Vector3f(0.1f,0.1f,0.1f)); + directionalLight.setDiffuse(new Vector3f(0.3f,0.3f,0.3f)); + directionalLight.setDirection(sunPosition); + directionalLight.setSpecular(new Vector3f(0.0f,0.0f,0.0f)); + + pointLights = new PointLight[POINT_LIGHT_COUNT]; + for(int i = 0; i < POINT_LIGHT_COUNT; i++){ + pointLights[i] = new PointLight(new Vector3f(0,0,0),new Vector3f(0,0,0)); + } + + pointLights[0].setAmbient(new Vector3f(0.924500f, 0.369800f, 0.092450f)); + pointLights[0].setConstant(1.0f); + pointLights[0].setDiffuse(new Vector3f(0.924500f, 0.369800f, 0.092450f)); + pointLights[0].setLinear(0.7f); + pointLights[0].setPosition(new Vector3f(1.0f,0.05f,1.0f)); + pointLights[0].setQuadratic(1.8f); + pointLights[0].setSpecular(new Vector3f(0.0f,0.0f,0.0f)); + + /* + Vector3f lightLoc = new Vector3f(0.2f,-1.0f,0.3f); + float temp[] = new float[3]; + temp[0] = lightLoc.x; + temp[1] = lightLoc.y; + temp[2] = lightLoc.z; + glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.direction"), temp); + + temp[0] = 0.4f; + temp[1] = 0.4f; + temp[2] = 0.4f; + glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.ambient"), temp); + + temp[0] = 0.3f; + temp[1] = 0.3f; + temp[2] = 0.3f; + glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.diffuse"), temp); + + temp[0] = 0.1f; + temp[1] = 0.1f; + temp[2] = 0.1f; + glUniform3fv(glGetUniformLocation(Globals.renderingEngine.getActiveShader().shaderProgram, "dirLight.specular"), temp); + + temp[0] = 32f; + */ + + //glBufferData(GL_UNIFORM_BUFFER, , GL_STATIC_DRAW); + } + + /** + * Call in each mesh / per each shader + * @param shaderIndex + */ + public void bindBuffer(int shaderIndex){ + //get position of lights object in shader + 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); + } + + /** + * Call once per render loop to set buffer values + */ + public void updateData(){ + putDataInBuffer(); + bufferData(); + } + + void bufferData(){ + glBindBuffer(GL_UNIFORM_BUFFER, uboIndex); + int offset = 0; + glBufferData(GL_UNIFORM_BUFFER, dataBuffer, GL_DYNAMIC_DRAW); + // glBufferSubData(GL_UNIFORM_BUFFER, offset, dataBuffer); + glBindBuffer(GL_UNIFORM_BUFFER, 0); + } + + void putDataInBuffer(){ + //implicitly flips + dataBuffer.clear(); + + //direct light + //vec3 dirLightDirection + dataBuffer.putFloat(directionalLight.direction.x); + dataBuffer.putFloat(directionalLight.direction.y); + dataBuffer.putFloat(directionalLight.direction.z); + dataBuffer.putFloat(0); + //vec3 dirLightAmbient + dataBuffer.putFloat(directionalLight.ambient.x); + dataBuffer.putFloat(directionalLight.ambient.y); + dataBuffer.putFloat(directionalLight.ambient.z); + dataBuffer.putFloat(0); + //vec3 dirLightDiffuse + dataBuffer.putFloat(directionalLight.diffuse.x); + dataBuffer.putFloat(directionalLight.diffuse.y); + dataBuffer.putFloat(directionalLight.diffuse.z); + dataBuffer.putFloat(0); + //vec3 dirLightSpecular + dataBuffer.putFloat(directionalLight.specular.x); + dataBuffer.putFloat(directionalLight.specular.y); + dataBuffer.putFloat(directionalLight.specular.z); + dataBuffer.putFloat(0); + + //point light + //vec3 position[10] + //dont sub cam + // for(int i = 0; i < POINT_LIGHT_COUNT; i++){ + // PointLight light = pointLights[i]; + // dataBuffer.putFloat(light.position.x); + // dataBuffer.putFloat(light.position.y); + // dataBuffer.putFloat(light.position.z); + // dataBuffer.putFloat(0); + // } + //do sub cam + if(Globals.playerCamera != null){ + Vector3f cameraPos = CameraEntityUtils.getCameraCenter(Globals.playerCamera); + for(int i = 0; i < POINT_LIGHT_COUNT; i++){ + PointLight light = pointLights[i]; + dataBuffer.putFloat(light.position.x - cameraPos.x); + dataBuffer.putFloat(light.position.y - cameraPos.y); + dataBuffer.putFloat(light.position.z - cameraPos.z); + dataBuffer.putFloat(0); + } + } + //float constant[10] + for(int i = 0; i < POINT_LIGHT_COUNT; i++){ + PointLight light = pointLights[i]; + dataBuffer.putFloat(light.constant); + dataBuffer.putFloat(0); + dataBuffer.putFloat(0); + dataBuffer.putFloat(0); + } + //float linear[10] + for(int i = 0; i < POINT_LIGHT_COUNT; i++){ + PointLight light = pointLights[i]; + dataBuffer.putFloat(light.linear); + dataBuffer.putFloat(0); + dataBuffer.putFloat(0); + dataBuffer.putFloat(0); + } + //float quadratic[10] + for(int i = 0; i < POINT_LIGHT_COUNT; i++){ + PointLight light = pointLights[i]; + dataBuffer.putFloat(light.quadratic); + dataBuffer.putFloat(0); + dataBuffer.putFloat(0); + dataBuffer.putFloat(0); + } + //vec3 ambient[10] + for(int i = 0; i < POINT_LIGHT_COUNT; i++){ + PointLight light = pointLights[i]; + dataBuffer.putFloat(light.ambient.x); + dataBuffer.putFloat(light.ambient.y); + dataBuffer.putFloat(light.ambient.z); + dataBuffer.putFloat(0); + } + //vec3 diffuse[10] + for(int i = 0; i < POINT_LIGHT_COUNT; i++){ + PointLight light = pointLights[i]; + dataBuffer.putFloat(light.diffuse.x); + dataBuffer.putFloat(light.diffuse.y); + dataBuffer.putFloat(light.diffuse.z); + dataBuffer.putFloat(0); + } + //vec3 specular[10] + for(int i = 0; i < POINT_LIGHT_COUNT; i++){ + PointLight light = pointLights[i]; + dataBuffer.putFloat(light.specular.x); + dataBuffer.putFloat(light.specular.y); + dataBuffer.putFloat(light.specular.z); + dataBuffer.putFloat(0); + } + + dataBuffer.flip(); + + // dataBuffer.position(0); + + } + } \ No newline at end of file