]> code.bitgloo.com Git - clyne/gamedev2.git/commitdiff
Added LIGHTING
authorAndy Belle-Isle <drumsetmonkey@gmail.com>
Mon, 2 Sep 2019 04:08:38 +0000 (00:08 -0400)
committerAndy Belle-Isle <drumsetmonkey@gmail.com>
Mon, 2 Sep 2019 04:08:38 +0000 (00:08 -0400)
Scripts/init.lua
Shaders/world.frag
Shaders/world.vert
src/components/Light.hpp [new file with mode: 0644]
src/components/Render.hpp
src/render.cpp
src/script.cpp

index 9983c986d5cb2685d95bc21596ccef575c5ebb7e..37b1f0d7be19ef5978e4e2fb99917a64e531d575 100644 (file)
@@ -17,6 +17,12 @@ bird = {
         texture = "Assets/player.png",
         visible = true
     },
+    Light = {
+        r = 1.0,
+        g = 1.0,
+        b = 1.0,
+        strength = 1.0
+    },
     Idle = function(self)
         --if (self.visibleTick >= 20) then
         --    self.Render.visible = not self.Render.visible
@@ -38,6 +44,7 @@ cat = {
     },
     Render = {
         texture = "Assets/cat.png",
+        normal = "Assets/cat_normal.png",
         visible = true
     },
     Init = function(self)
@@ -61,6 +68,12 @@ animal = {
         texture = "Assets/rabbit.png",
         visible = true
     },
+    Light = {
+        r = 0.0,
+        b = 1.0,
+        g = 0.2,
+        strength = 2.0
+    },
     Idle = function(self)
         self.Velocity.x = -200 * math.sin(math.rad(self.counter));
         self.Velocity.y =  500 * math.cos(math.rad(self.counter*5));
@@ -69,8 +82,40 @@ animal = {
     counter = 0;
 }
 
+wall = {
+    Position = {
+        y = -100
+    },
+    Render = {
+        texture = "Assets/rock.png",
+        normal = "Assets/rock_normal.png",
+        visible = true
+    }
+}
+
 birdSpawn = game.spawn(bird);
 
 dogSpawn = game.spawn(cat);
 
 animalSpawn = game.spawn(animal);
+
+wallSpawn = game.spawn(wall);
+
+game.spawn({
+    Velocity = {
+        x = 0,
+        y = 0
+    },
+    Light = {
+        r = 0.8,
+        g = 0.1,
+        b = 0.2,
+        strength = 0.75
+    },
+    counter = 0;
+    Idle = function(self)
+        self.Velocity.x = -100 * math.sin(math.rad(self.counter));
+        self.Velocity.y =  100 * math.cos(math.rad(self.counter));
+        self.counter = self.counter + 5;
+    end
+});
index ded3ec0ea03826cd4d2c1f983812ee75400d26f2..5ef399dedcd7974857696706f54c601339368b9e 100644 (file)
@@ -7,11 +7,94 @@ precision mediump float;
 #endif
 
 uniform sampler2D textu;
+uniform sampler2D normu;
 
 in vec2 texCoord;
+in vec4 fragCoord;
 out vec4 FragColor;
 
+uniform vec3 LightPos[32];
+uniform vec4 LightColor[32];
+uniform int LightNum;
+
 void main()
 {
-    FragColor = texture(textu, texCoord);
+    //vec3 LightPos = vec3(0.0, 0.0, 0.0);
+    //vec4 LightColor = vec4(1.0, 1.0, 1.0, 1.0);
+    vec3 Falloff = vec3(0.1, 0.2, 0.0);
+
+    vec4 DiffuseColor = texture2D(textu, texCoord);
+
+    if (DiffuseColor.a < 0.1f)
+        discard;
+
+    vec3 NormalMap = texture2D(normu, texCoord).rgb;
+    vec3 SumLight = vec3(0.0);
+
+    for (int i = 0; i < LightNum; i++) {
+        vec3 LightDir = vec3(LightPos[i].xy - fragCoord.xy, LightPos[i].z);
+
+        float D = length(LightDir);
+
+        vec3 N = normalize(NormalMap * 2.0 - 1.0);
+        vec3 L = normalize(LightDir);
+
+        vec3 Diffuse = (LightColor[i].rgb * LightColor[i].a) * max(dot(N, L), 0.0);
+
+        vec3 Ambient = vec3(0.0);
+
+        float Attenuation = 
+            1.0 / (Falloff.x + (Falloff.y * D) + (Falloff.z * D * D));
+
+        vec3 Intensity = Ambient + Diffuse + Attenuation;
+        vec3 FinalColor = DiffuseColor.rgb * Intensity;
+
+        SumLight += FinalColor;
+    }
+
+    FragColor = vec4(SumLight, DiffuseColor.a);
+};
+
+/*
+    vec4 normalMap = texture2D(normu, texCoord);
+    vec3 normal = normalMap.xyz * 2.0 - 1.0;
+
+    if (pixTex.a < 0.1f) 
+               discard;
+
+       vec4 shadeColor = vec4(0.0f, 0.0f, 0.0f, 0.0f);
+
+    float dist = length(light.xy - fragCoord.xy);
+    if (dist < light.w) {
+        float attenuation = clamp(1.0f - dist*dist/(light.w*light.w), 0.0f, 1.0f);
+        attenuation *= attenuation;
+        shadeColor += vec4(attenuation, attenuation, attenuation, 1.0f) * vec4(normal.xyz, 1);
+        //shadeColor = vec4(1.0) + 0.1*normal;
+        //shadeColor = vec4(1.0);
+    }
+
+    //FragColor = pixTex * shadeColor;
+    FragColor = vec4(normal.xyz, 1);
 }
+*/
+
+/*
+    vec2 texLoc = vec2(texCoord.x, 1-texCoord.y);
+       vec4 pixTex = texture2D(texture, texLoc);
+    if (pixTex.a < 0.1f) 
+               discard;
+   
+       vec4 shadeColor = vec4(0.0f, 0.0f, 0.0f, 0.0f);
+       if (lightImpact > 0.0f) {
+               for (int i = 0; i < lightSize; i++) {
+                       vec2 loc = light[i].xy;
+                       float dist = length(loc - fragCoord.xy);
+                       if (dist < light[i].w) {
+                               float attenuation = clamp(1.0f - dist*dist/(light[i].w*light[i].w), 0.0f, 1.0f);
+                               attenuation *= attenuation;
+                               shadeColor += (vec4(attenuation, attenuation, attenuation, 0.0f) * vec4(lightColor[i])) * lightImpact;
+                       }
+               }
+       }
+       shadeColor += ambientLight;
+*/
index 743ff3de4d25d875eda40845f6dbe045e4448c22..0760183b332a8773382d6cc5a73351d25a5af0dd 100644 (file)
@@ -9,9 +9,11 @@ uniform mat4 view;
 uniform mat4 model;
 
 out vec2 texCoord;
+out vec4 fragCoord;
 
 void main()
 {
     texCoord = texc;
-    gl_Position = projection * view * model * vec4(vertex, 1.0f);
+    fragCoord = vec4(vertex, 1.0f);
+    gl_Position = projection * view * model * fragCoord;
 }
diff --git a/src/components/Light.hpp b/src/components/Light.hpp
new file mode 100644 (file)
index 0000000..ee215a6
--- /dev/null
@@ -0,0 +1,54 @@
+/**
+ * @file Light.hpp
+ *
+ * Copyright (C) 2019  Belle-Isle, Andrew <drumsetmonkey@gmail.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef COMPONENT_LIGHT_HPP_
+#define COMPONENT_LIGHT_HPP_
+
+#include "Component.hpp"
+
+struct Light : Component<Light>, entityx::Component<Light>
+{
+public:
+    float r, g, b;
+    float strength;
+
+    Light() {}
+    Light(float _r, float _g, float _z, float _s) :
+        r(_r), g(_g), b(_z), strength(_s) {}
+
+    Light FromLua(sol::object ref)
+    {
+        if (ref.get_type() == sol::type::table) {
+            sol::table tab = ref;
+            if (tab["r"] == sol::type::number)
+                this->r = tab["r"];
+            if (tab["g"] == sol::type::number)
+                this->g = tab["g"];
+            if (tab["b"] == sol::type::number)
+                this->b = tab["b"];
+            if (tab["strength"] == sol::type::number)
+                this->strength = tab["strength"];
+        } else {
+            throw std::string("Light component must be a table");
+        }
+        return *this;
+    }
+};
+
+#endif//COMPONENT_LIGHT_HPP_
index 6cc26dbdd91f35a53c8b86528b1724c47dc26f75..f5936ea6c8f3a65527d51362c1c332670fd61877 100644 (file)
@@ -25,7 +25,9 @@ struct Render : Component<Render>, entityx::Component<Render>
 {
 public:
     Texture texture;
+    Texture normal;
     bool visible;
+    bool hasNormal = false;
 
     Render(std::string _file) :
         texture(_file), visible(true) {}
@@ -40,6 +42,10 @@ public:
                 this->visible = tab["visible"];
             if (tab["texture"].get_type() == sol::type::string)
                 this->texture = Texture(static_cast<std::string>(tab["texture"]));
+            if (tab["normal"].get_type() == sol::type::string) {
+                this->normal = Texture(static_cast<std::string>(tab["normal"]));
+                hasNormal = true;
+            }
         } else {
             throw std::string(
                 "Render component table formatted incorrectly"
index 8e9cbdf933cc08bfc652df28e8a0fd4675e2be03..bd168edcce26d210866a4173b82437c2947be97d 100644 (file)
@@ -21,6 +21,7 @@
 #include <render.hpp>
 #include <components/Render.hpp>
 #include <components/Position.hpp>
+#include <components/Light.hpp>
 
 void RenderSystem::configure([[maybe_unused]] entityx::EntityManager& entities,
                              [[maybe_unused]] entityx::EventManager& events)
@@ -40,6 +41,7 @@ void RenderSystem::update([[maybe_unused]] entityx::EntityManager& entities,
     GLuint t = worldShader.getAttribute("texc");
 
     GLuint q = worldShader.getUniform("textu");
+    GLuint n = worldShader.getUniform("normu");
 
     /***********
     *  SETUP  *
@@ -84,8 +86,29 @@ void RenderSystem::update([[maybe_unused]] entityx::EntityManager& entities,
     *  DRAWING  *
     *************/
 
+    std::vector<glm::vec3> lightPos;
+    std::vector<glm::vec4> lightColor;
+    int lightNum = 0;
+
+    entities.each<Light, Position>(
+        [&]
+        (entityx::Entity, Light &l, Position &p){
+
+        lightPos.push_back(glm::vec3(p.x, p.y, 0.0));
+        lightColor.push_back(glm::vec4(l.r, l.g, l.b, l.strength));
+        lightNum++;
+    });
+
+    glUniform1i(worldShader.getUniform("LightNum"), lightNum);
+    glUniform3fv(worldShader.getUniform("LightPos"), 
+                 lightPos.size(),
+                 reinterpret_cast<GLfloat*>(lightPos.data()));
+    glUniform4fv(worldShader.getUniform("LightColor"),
+                 lightColor.size(),
+                 reinterpret_cast<GLfloat*>(lightColor.data()));
+
     entities.each<Render, Position>(
-        [this, a, q, t](entityx::Entity, Render &r, Position &p) {
+        [this, a, q, t, n](entityx::Entity, Render &r, Position &p) {
 
         if (!r.visible)
             return;
@@ -108,6 +131,10 @@ void RenderSystem::update([[maybe_unused]] entityx::EntityManager& entities,
         glBindTexture(GL_TEXTURE_2D, r.texture.tex);
         glUniform1i(q, 0);
 
+        glActiveTexture(GL_TEXTURE1);
+        glBindTexture(GL_TEXTURE_2D, r.normal.tex);
+        glUniform1i(n, 1);
+
         glGenBuffers(1, &tri_vbo);
         glBindBuffer(GL_ARRAY_BUFFER, tri_vbo);
         glBufferData(GL_ARRAY_BUFFER, sizeof(tri_data), tri_data, GL_STREAM_DRAW);
@@ -183,6 +210,11 @@ int RenderSystem::init(void)
     worldShader.addAttribute("texc");
 
     worldShader.addUniform("textu");
+    worldShader.addUniform("normu");
+
+    worldShader.addUniform("LightPos");
+    worldShader.addUniform("LightColor");
+    worldShader.addUniform("LightNum");
 
     glEnableVertexAttribArray(worldShader.getAttribute("vertex"));
     glUseProgram(worldShader.getProgram());
@@ -190,7 +222,7 @@ int RenderSystem::init(void)
     // TODO
     //glPolygonOffset(1.0, 1.0);
 
-    glClearColor(0.6, 0.8, 1.0, 0.0);
+    //glClearColor(0.6, 0.8, 1.0, 0.0);
 
     return 0;
 }
index 80ac53858cd955e0cc49bab7465ac0df7d3637d9..30328ab623ee4c65fcd54a8e261734e5d356956a 100644 (file)
@@ -80,6 +80,7 @@ void ScriptSystem::doFile(void)
 #include <components/Render.hpp>
 #include <components/Script.hpp>
 #include <components/Velocity.hpp>
+#include <components/Light.hpp>
 
 void ScriptSystem::scriptExport(void)
 {
@@ -108,6 +109,13 @@ void ScriptSystem::scriptExport(void)
     lua.new_usertype<Player>("Player",
             sol::constructors<Player(void), Player()>());
 
+    lua.new_usertype<Light>("Light",
+            sol::constructors<Light(float, float, float, float)>(),
+            "r", &Light::r,
+            "g", &Light::g,
+            "b", &Light::b,
+            "strength", &Light::strength);
+
     auto gamespace = lua["game"].get_or_create<sol::table>();
     gamespace.set_function("spawn", func);
 }
@@ -162,6 +170,11 @@ sol::table ScriptSystem::spawn(sol::object param)
             (*toRet)["Player"] = e.assign<Player>().get();
         }
 
+        if (tab["Light"] != nullptr) {
+            (*toRet)["Light"] = 
+                e.assign<Light>(Light().FromLua(tab["Light"])).get();
+        }
+
     } else {
         // TODO better logging
         std::cerr << "Parameter to spawn() must be a table!" << std::endl;