changeset 25:2403030a0352

"Finish" implementing multiple lights support in scene files. If scene defines no lights, a default light will be used. Light objects will have default values and can redefine only color, position etc.
author Matti Hamalainen <ccr@tnsp.org>
date Fri, 22 Nov 2019 06:47:13 +0200
parents c1897cfc8463
children 67647ed860f0
files dmmodel.cpp dmmodel.h dragon.scene gldragon.cpp
diffstat 4 files changed, 62 insertions(+), 35 deletions(-) [+]
line wrap: on
line diff
--- a/dmmodel.cpp	Fri Nov 22 05:49:14 2019 +0200
+++ b/dmmodel.cpp	Fri Nov 22 06:47:13 2019 +0200
@@ -594,21 +594,19 @@
 
 bool dmParseVector(DMTextFileInfo &info, const std::vector<std::string> tokens, const size_t offs, DMVector4 &vec)
 {
-    vec.w = 1.0f;
-
     if (tokens.size() == offs + 1)
     {
-        vec.x = vec.y = vec.z = std::stof(tokens[offs]);
+        vec.p.x = vec.p.y = vec.p.z = std::stof(tokens[offs]);
     }
     else
     if (tokens.size() == offs + 3 || tokens.size() == offs + 4)
     {
-        vec.x = std::stof(tokens[offs]);
-        vec.y = std::stof(tokens[offs + 1]);
-        vec.z = std::stof(tokens[offs + 2]);
+        vec.p.x = std::stof(tokens[offs]);
+        vec.p.y = std::stof(tokens[offs + 1]);
+        vec.p.z = std::stof(tokens[offs + 2]);
 
         if (tokens.size() == offs + 4)
-            vec.w = std::stof(tokens[offs + 3]);
+            vec.p.w = std::stof(tokens[offs + 3]);
     }
     else
     {
@@ -653,7 +651,7 @@
     DMTextFileInfo info;
     DMModel *model = 0;
     DMLight *light = 0;
-    DMVector3 *ppos = 0, *ppointAt = 0;
+    DMVector4 *ppos = 0, *ppointAt = 0;
 
     info.filename = filename;
     info.nline = info.state = 0;
@@ -741,7 +739,7 @@
             }
             lights.push_back(newlight);
             light = &lights.back();
-            ppos = &light->pos;
+            ppos = &light->position;
             ppointAt = &light->pointAt;
             info.state = 2;
         }
@@ -749,6 +747,7 @@
         if (info.state == 2 && (key == "ambient" || key == "diffuse" || key == "specular"))
         {
             DMVector4 val;
+            val.p.w = 1.0f;
 
             if (!dmParseVector(info, tokens, 1, val))
                 return false;
@@ -767,18 +766,20 @@
         {
             info.state = 3;
 
-            ppos = &camera.pos;
+            ppos = &camera.position;
             ppointAt = &camera.pointAt;
         }
         else
-        if ((info.state == 3 || info.state == 2) && (key == "pos" || key == "point_at"))
+        if ((info.state == 3 || info.state == 2) &&
+            (key == "position" || key == "pos" || key == "point_at"))
         {
-            DMVector3 vec;
+            DMVector4 vec;
+            vec.p.w = 0;
 
             if (!dmParseVector(info, tokens, 1, vec))
                 return false;
 
-            if (key == "pos")
+            if (key == "position" || key == "pos")
                 *ppos = vec;
             else
             if (key == "point_at")
--- a/dmmodel.h	Fri Nov 22 05:49:14 2019 +0200
+++ b/dmmodel.h	Fri Nov 22 06:47:13 2019 +0200
@@ -133,9 +133,10 @@
 };
 
 
-struct DMVector4
+union DMVector4
 {
-    float x, y, z, w;
+    struct { float x, y, z, w; } p;
+    float values[4];
 };
 
 
@@ -183,14 +184,26 @@
 
 struct DMLight
 {
-    DMVector3 pos, pointAt;
-    DMVector4 ambient, diffuse, specular;
+    DMVector4
+        ambient, diffuse, specular,
+        position, pointAt;
+
+    DMLight()
+    {
+        ambient.p.x  = ambient.p.y  = ambient.p.z  = 0.2f; ambient.p.w  = 1.0f;
+        diffuse.p.x  = diffuse.p.y  = diffuse.p.z  = 0.8f; diffuse.p.w  = 1.0f;
+        specular.p.x = specular.p.y = specular.p.z = 0.5f; specular.p.w = 1.0f;
+
+        position.p.x = 10.0f;
+        position.p.y = 10.0f;
+        position.p.z =  0.0f;
+    }
 };
 
 
 struct DMCamera
 {
-    DMVector3 pos, pointAt;
+    DMVector4 position, pointAt;
 };
 
 
--- a/dragon.scene	Fri Nov 22 05:49:14 2019 +0200
+++ b/dragon.scene	Fri Nov 22 06:47:13 2019 +0200
@@ -1,1 +1,8 @@
 model dragon.ply
+
+light
+	position 10 10 0.0
+
+light
+	diffuse 1.0 0 0
+	position -50 50 0
--- a/gldragon.cpp	Fri Nov 22 05:49:14 2019 +0200
+++ b/gldragon.cpp	Fri Nov 22 06:47:13 2019 +0200
@@ -185,7 +185,7 @@
 
     // Add transforms
     glScalef(model.scale.x, model.scale.y, model.scale.z);
-    glTranslatef(model.translate.x, model.translate.y, model.translate. z);
+    glTranslatef(model.translate.x, model.translate.y, model.translate.z);
     glRotatef(model.rotate.x, 1.0f, 0.0f, 0.0f);
     glRotatef(model.rotate.y, 0.0f, 1.0f, 0.0f);
     glRotatef(model.rotate.z, 0.0f, 0.0f, 1.0f);
@@ -286,6 +286,16 @@
 }
 
 
+void dmSetupLight(const int n, const DMLight &light)
+{
+    glEnable(GL_LIGHT0 + n);
+    glLightfv(GL_LIGHT0 + n, GL_AMBIENT, light.ambient.values);
+    glLightfv(GL_LIGHT0 + n, GL_DIFFUSE, light.diffuse.values);
+    glLightfv(GL_LIGHT0 + n, GL_SPECULAR, light.specular.values);
+    glLightfv(GL_LIGHT0 + n, GL_POSITION, light.position.values);
+}
+
+
 int main(int argc, char *argv[])
 {
     int startTime, cycleStart, cycleFrames = 0, totalFrames = 0;
@@ -438,29 +448,25 @@
             dmLinkModelShaders(model);
         }
     }
-    else
+
     {
         float specReflection[] = { 0.8f, 0.8f, 0.8f, 1.0f };
-
         glEnable(GL_COLOR_MATERIAL);
-
         glColorMaterial(GL_FRONT, GL_AMBIENT_AND_DIFFUSE);
         glMateriali(GL_FRONT, GL_SHININESS, 96);
         glMaterialfv(GL_FRONT, GL_SPECULAR, specReflection);
-
-        glEnable(GL_LIGHT0);
+    }
 
-        // Define the light components and position
-        GLfloat ambient[]  = {   0.2f,  0.2f,  0.2f,  1.0f };
-        GLfloat diffuse[]  = {   0.8f,  0.8f,  0.8f,  1.0f };
-        GLfloat specular[] = {   0.5f,  0.5f,  0.5f,  1.0f };
-        GLfloat position[] = {  10.0f, 10.0f,  0.0f,  0.0f };
-
-        // Define the light components and position
-        glLightfv(GL_LIGHT0, GL_AMBIENT, ambient);
-        glLightfv(GL_LIGHT0, GL_DIFFUSE, diffuse);
-        glLightfv(GL_LIGHT0, GL_SPECULAR, specular);
-        glLightfv(GL_LIGHT0, GL_POSITION, position);
+    // Define lights
+    if (scene.lights.size() == 0)
+    {
+        DMLight light; // Default light
+        dmSetupLight(0, light);
+    }
+    else
+    {
+        for (size_t n = 0; n < scene.lights.size(); n++)
+            dmSetupLight(n, scene.lights[n]);
     }
 
     // Define the camera