]> git.jsancho.org Git - lugaru.git/commitdiff
Cleaned Terrain Decal handling
authorCôme Chilliet <come@chilliet.eu>
Thu, 22 Dec 2016 23:44:28 +0000 (00:44 +0100)
committerCôme Chilliet <come@chilliet.eu>
Thu, 22 Dec 2016 23:44:28 +0000 (00:44 +0100)
13 files changed:
CMakeLists.txt
Source/Environment/Terrain.cpp
Source/Environment/Terrain.hpp
Source/GameDraw.cpp
Source/GameTick.cpp
Source/Globals.cpp
Source/Graphic/Decal.cpp [new file with mode: 0644]
Source/Graphic/Decal.hpp [new file with mode: 0644]
Source/Graphic/Models.cpp
Source/Menu/Menu.cpp
Source/Objects/Person.cpp
Source/User/Settings.cpp
Source/User/Settings.hpp

index 4b6094c8408953d64902a3062a8c0a171e4462e6..62d5bd97206f5d0ef108b1cf68beb53e2c3ad466 100644 (file)
@@ -54,6 +54,7 @@ set(LUGARU_SRCS
     ${SRCDIR}/Environment/Lights.cpp
     ${SRCDIR}/Environment/Skybox.cpp
     ${SRCDIR}/Environment/Terrain.cpp
+    ${SRCDIR}/Graphic/Decal.cpp
     ${SRCDIR}/Graphic/Models.cpp
     ${SRCDIR}/Graphic/Sprite.cpp
     ${SRCDIR}/Graphic/Stereo.cpp
@@ -97,6 +98,7 @@ set(LUGARU_H
     ${SRCDIR}/Environment/Lights.hpp
     ${SRCDIR}/Environment/Skybox.hpp
     ${SRCDIR}/Environment/Terrain.hpp
+    ${SRCDIR}/Graphic/Decal.hpp
     ${SRCDIR}/Graphic/gamegl.hpp
     ${SRCDIR}/Graphic/Models.hpp
     ${SRCDIR}/Graphic/Sprite.hpp
index 9c8b96a3073e638da939399f32c5bcbcfb66aa4a..d22ecdfc749cbc1c7ad05aaff15a7b65e4f5d8f9 100644 (file)
@@ -35,7 +35,7 @@ extern float multiplier;
 extern FRUSTUM frustum;
 extern float texdetail;
 extern int detail;
-extern bool decals;
+extern bool decalstoggle;
 extern float blurness;
 extern float targetblurness;
 extern bool skyboxtexture;
@@ -995,8 +995,7 @@ void Terrain::draw(int layer)
 
 void Terrain::drawdecals()
 {
-    if (decals) {
-        static int i;
+    if (decalstoggle) {
         static float distancemult;
         static int lasttype;
 
@@ -1012,10 +1011,10 @@ void Terrain::drawdecals()
         glDisable(GL_CULL_FACE);
         glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
         glDepthMask(0);
-        for (i = 0; i < numdecals; i++) {
-            if (decaltype[i] == blooddecalfast && decalalivetime[i] < 2)
-                decalalivetime[i] = 2;
-            if ((decaltype[i] == shadowdecal || decaltype[i] == shadowdecalpermanent) && decaltype[i] != lasttype) {
+        for (unsigned int i = 0; i < decals.size(); i++) {
+            if (decals[i].type == blooddecalfast && decals[i].alivetime < 2)
+                decals[i].alivetime = 2;
+            if ((decals[i].type == shadowdecal || decals[i].type == shadowdecalpermanent) && decals[i].type != lasttype) {
                 shadowtexture.bind();
                 if (!blend) {
                     blend = 1;
@@ -1023,7 +1022,7 @@ void Terrain::drawdecals()
                     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                 }
             }
-            if (decaltype[i] == footprintdecal && decaltype[i] != lasttype) {
+            if (decals[i].type == footprintdecal && decals[i].type != lasttype) {
                 footprinttexture.bind();
                 if (!blend) {
                     blend = 1;
@@ -1031,7 +1030,7 @@ void Terrain::drawdecals()
                     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                 }
             }
-            if (decaltype[i] == bodyprintdecal && decaltype[i] != lasttype) {
+            if (decals[i].type == bodyprintdecal && decals[i].type != lasttype) {
                 bodyprinttexture.bind();
                 if (!blend) {
                     blend = 1;
@@ -1039,7 +1038,7 @@ void Terrain::drawdecals()
                     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
                 }
             }
-            if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalslow) && decaltype[i] != lasttype) {
+            if ((decals[i].type == blooddecal || decals[i].type == blooddecalslow) && decals[i].type != lasttype) {
                 bloodtexture.bind();
                 if (blend) {
                     blend = 0;
@@ -1047,7 +1046,7 @@ void Terrain::drawdecals()
                     glBlendFunc(GL_ONE, GL_ZERO);
                 }
             }
-            if ((decaltype[i] == blooddecalfast) && decaltype[i] != lasttype) {
+            if ((decals[i].type == blooddecalfast) && decals[i].type != lasttype) {
                 bloodtexture2.bind();
                 if (blend) {
                     blend = 0;
@@ -1055,44 +1054,44 @@ void Terrain::drawdecals()
                     glBlendFunc(GL_ONE, GL_ZERO);
                 }
             }
-            if (decaltype[i] == shadowdecal || decaltype[i] == shadowdecalpermanent) {
-                distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
+            if (decals[i].type == shadowdecal || decals[i].type == shadowdecalpermanent) {
+                distancemult = (viewdistsquared - (distsq(&viewer, &decals[i].position) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
                 if (distancemult >= 1)
-                    glColor4f(1, 1, 1, decalopacity[i]);
+                    glColor4f(1, 1, 1, decals[i].opacity);
                 if (distancemult < 1)
-                    glColor4f(1, 1, 1, decalopacity[i]*distancemult);
+                    glColor4f(1, 1, 1, decals[i].opacity*distancemult);
             }
-            if (decaltype[i] == footprintdecal || decaltype[i] == bodyprintdecal) {
-                distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
+            if (decals[i].type == footprintdecal || decals[i].type == bodyprintdecal) {
+                distancemult = (viewdistsquared - (distsq(&viewer, &decals[i].position) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
                 if (distancemult >= 1) {
-                    glColor4f(1, 1, 1, decalopacity[i]);
-                    if (decalalivetime[i] > 3)
-                        glColor4f(1, 1, 1, decalopacity[i] * (5 - decalalivetime[i]) / 2);
+                    glColor4f(1, 1, 1, decals[i].opacity);
+                    if (decals[i].alivetime > 3)
+                        glColor4f(1, 1, 1, decals[i].opacity * (5 - decals[i].alivetime) / 2);
                 }
                 if (distancemult < 1) {
-                    glColor4f(1, 1, 1, decalopacity[i]*distancemult);
-                    if (decalalivetime[i] > 3)
-                        glColor4f(1, 1, 1, decalopacity[i] * (5 - decalalivetime[i]) / 2 * distancemult);
+                    glColor4f(1, 1, 1, decals[i].opacity*distancemult);
+                    if (decals[i].alivetime > 3)
+                        glColor4f(1, 1, 1, decals[i].opacity * (5 - decals[i].alivetime) / 2 * distancemult);
                 }
             }
-            if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow)) {
-                distancemult = (viewdistsquared - (distsq(&viewer, &decalposition[i]) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
+            if ((decals[i].type == blooddecal || decals[i].type == blooddecalfast || decals[i].type == blooddecalslow)) {
+                distancemult = (viewdistsquared - (distsq(&viewer, &decals[i].position) - (viewdistsquared * fadestart)) * (1 / (1 - fadestart))) / viewdistsquared;
                 if (distancemult >= 1) {
-                    glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]);
-                    if (decalalivetime[i] < 4)
-                        glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*decalalivetime[i]*.25);
-                    if (decalalivetime[i] > 58)
-                        glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i] * (60 - decalalivetime[i]) / 2);
+                    glColor4f(decals[i].brightness, decals[i].brightness, decals[i].brightness, decals[i].opacity);
+                    if (decals[i].alivetime < 4)
+                        glColor4f(decals[i].brightness, decals[i].brightness, decals[i].brightness, decals[i].opacity*decals[i].alivetime*.25);
+                    if (decals[i].alivetime > 58)
+                        glColor4f(decals[i].brightness, decals[i].brightness, decals[i].brightness, decals[i].opacity * (60 - decals[i].alivetime) / 2);
                 }
                 if (distancemult < 1) {
-                    glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*distancemult);
-                    if (decalalivetime[i] < 4)
-                        glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i]*decalalivetime[i]*distancemult * .25);
-                    if (decalalivetime[i] > 58)
-                        glColor4f(decalbrightness[i], decalbrightness[i], decalbrightness[i], decalopacity[i] * (60 - decalalivetime[i]) / 2 * distancemult);
+                    glColor4f(decals[i].brightness, decals[i].brightness, decals[i].brightness, decals[i].opacity*distancemult);
+                    if (decals[i].alivetime < 4)
+                        glColor4f(decals[i].brightness, decals[i].brightness, decals[i].brightness, decals[i].opacity*decals[i].alivetime*distancemult * .25);
+                    if (decals[i].alivetime > 58)
+                        glColor4f(decals[i].brightness, decals[i].brightness, decals[i].brightness, decals[i].opacity * (60 - decals[i].alivetime) / 2 * distancemult);
                 }
             }
-            lasttype = decaltype[i];
+            lasttype = decals[i].type;
             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
             glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
 
@@ -1100,31 +1099,42 @@ void Terrain::drawdecals()
             glPushMatrix();
             glBegin(GL_TRIANGLES);
             for (int j = 0; j < 3; j++) {
-                glTexCoord2f(decaltexcoords[i][j][0], decaltexcoords[i][j][1]);
-                glVertex3f(decalvertex[i][j].x, decalvertex[i][j].y, decalvertex[i][j].z);
+                glTexCoord2f(decals[i].texcoords[j][0], decals[i].texcoords[j][1]);
+                glVertex3f(decals[i].vertex[j].x, decals[i].vertex[j].y, decals[i].vertex[j].z);
             }
             glEnd();
             glPopMatrix();
         }
-        for (i = numdecals - 1; i >= 0; i--) {
-            decalalivetime[i] += multiplier;
-            if (decaltype[i] == blooddecalslow)
-                decalalivetime[i] -= multiplier * 2 / 3;
-            if (decaltype[i] == blooddecalfast)
-                decalalivetime[i] += multiplier * 4;
-            if (decaltype[i] == shadowdecal)
+        for (int i = decals.size() - 1; i >= 0; i--) {
+            decals[i].alivetime += multiplier;
+            if (decals[i].type == blooddecalslow)
+                decals[i].alivetime -= multiplier * 2 / 3;
+            if (decals[i].type == blooddecalfast)
+                decals[i].alivetime += multiplier * 4;
+            if (decals[i].type == shadowdecal)
                 DeleteDecal(i);
-            if (decaltype[i] == footprintdecal && decalalivetime[i] >= 5)
+            if (decals[i].type == footprintdecal && decals[i].alivetime >= 5)
                 DeleteDecal(i);
-            if (decaltype[i] == bodyprintdecal && decalalivetime[i] >= 5)
+            if (decals[i].type == bodyprintdecal && decals[i].alivetime >= 5)
                 DeleteDecal(i);
-            if ((decaltype[i] == blooddecal || decaltype[i] == blooddecalfast || decaltype[i] == blooddecalslow) && decalalivetime[i] >= 60)
+            if ((decals[i].type == blooddecal || decals[i].type == blooddecalfast || decals[i].type == blooddecalslow) && decals[i].alivetime >= 60)
                 DeleteDecal(i);
         }
         glAlphaFunc(GL_GREATER, 0.0001);
     }
 }
 
+void Terrain::deleteDeadDecals()
+{
+    for (unsigned int i = 0; i < decals.size(); ) {
+        if ((decals[i].type == blooddecal || decals[i].type == blooddecalslow) && decals[i].alivetime < 2) {
+            DeleteDecal(i);
+        } else {
+            i++;
+        }
+    }
+}
+
 void Terrain::AddObject(XYZ where, float radius, int id)
 {
     XYZ points[4];
@@ -1161,32 +1171,18 @@ void Terrain::AddObject(XYZ where, float radius, int id)
 
 void Terrain::DeleteDecal(int which)
 {
-    if (decals) {
-        decaltype[which] = decaltype[numdecals - 1];
-        decalposition[which] = decalposition[numdecals - 1];
-        for (int i = 0; i < 3; i++) {
-            decalvertex[which][i] = decalvertex[numdecals - 1][i];
-            decaltexcoords[which][i][0] = decaltexcoords[numdecals - 1][i][0];
-            decaltexcoords[which][i][1] = decaltexcoords[numdecals - 1][i][1];
-        }
-        decalrotation[which] = decalrotation[numdecals - 1];
-        decalalivetime[which] = decalalivetime[numdecals - 1];
-        decalopacity[which] = decalopacity[numdecals - 1];
-        decalbrightness[which] = decalbrightness[numdecals - 1];
-        numdecals--;
+    if (decalstoggle) {
+        decals.erase(decals.begin() + which);
     }
 }
 
 void Terrain::MakeDecal(int type, XYZ where, float size, float opacity, float rotation)
 {
-    if (decals) {
+    if (decalstoggle) {
         if (opacity > 0 && size > 0) {
             static int patchx[4];
             static int patchy[4];
 
-            decaltexcoords[numdecals][0][0] = 1;
-            decaltexcoords[numdecals][0][1] = 0;
-
             patchx[0] = (where.x + size) / scale;
             patchx[1] = (where.x - size) / scale;
             patchx[2] = (where.x - size) / scale;
@@ -1208,146 +1204,46 @@ void Terrain::MakeDecal(int type, XYZ where, float size, float opacity, float ro
             if ((patchx[2] != patchx[3] || patchy[2] != patchy[3])) {
                 MakeDecalLock(type, where, patchx[2], patchy[2], size, opacity, rotation);
             }
+
             MakeDecalLock(type, where, patchx[3], patchy[3], size, opacity, rotation);
         }
     }
-    //}
 }
 
 void Terrain::MakeDecalLock(int type, XYZ where, int whichx, int whichy, float size, float opacity, float rotation)
 {
-    if (decals) {
-        static float placex, placez;
-        static XYZ rot;
+    if (decalstoggle) {
+        XYZ rot = getLighting(where.x, where.z);
+        float decalbright = (rot.x + rot.y + rot.z) / 3;
 
-        float decalbright;
-
-        rot = getLighting(where.x, where.z);
-        decalbrightness[numdecals] = (rot.x + rot.y + rot.z) / 3;
-        if (decalbrightness[numdecals] < .4)
-            decalbrightness[numdecals] = .4;
+        if (decalbright < .4)
+            decalbright = .4;
 
         if (environment == grassyenvironment) {
-            decalbrightness[numdecals] *= .6;
+            decalbright *= .6;
         }
 
-        if (decalbrightness[numdecals] > 1)
-            decalbrightness[numdecals] = 1;
-        decalbright = decalbrightness[numdecals];
-
-        decalposition[numdecals] = where;
-        decaltype[numdecals] = type;
-        decalopacity[numdecals] = opacity;
-        decalrotation[numdecals] = rotation;
-        decalalivetime[numdecals] = 0;
-
-        placex = (float)whichx * scale + scale;
-        placez = (float)whichy * scale;
-
-        decaltexcoords[numdecals][0][0] = (placex - where.x) / size / 2 + .5;
-        decaltexcoords[numdecals][0][1] = (placez - where.z) / size / 2 + .5;
-
-        decalvertex[numdecals][0].x = placex;
-        decalvertex[numdecals][0].z = placez;
-        decalvertex[numdecals][0].y = heightmap[whichx + 1][whichy] * scale + .01;
-
-
-        placex = (float)whichx * scale + scale;
-        placez = (float)whichy * scale + scale;
-
-        decaltexcoords[numdecals][1][0] = (placex - where.x) / size / 2 + .5;
-        decaltexcoords[numdecals][1][1] = (placez - where.z) / size / 2 + .5;
-
-        decalvertex[numdecals][1].x = placex;
-        decalvertex[numdecals][1].z = placez;
-        decalvertex[numdecals][1].y = heightmap[whichx + 1][whichy + 1] * scale + .01;
-
-
-        placex = (float)whichx * scale;
-        placez = (float)whichy * scale + scale;
-
-        decaltexcoords[numdecals][2][0] = (placex - where.x) / size / 2 + .5;
-        decaltexcoords[numdecals][2][1] = (placez - where.z) / size / 2 + .5;
-
-        decalvertex[numdecals][2].x = placex;
-        decalvertex[numdecals][2].z = placez;
-        decalvertex[numdecals][2].y = heightmap[whichx][whichy + 1] * scale + .01;
-
-        if (decalrotation[numdecals]) {
-            for (int i = 0; i < 3; i++) {
-                rot.y = 0;
-                rot.x = decaltexcoords[numdecals][i][0] - .5;
-                rot.z = decaltexcoords[numdecals][i][1] - .5;
-                rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
-                decaltexcoords[numdecals][i][0] = rot.x + .5;
-                decaltexcoords[numdecals][i][1] = rot.z + .5;
-            }
+        if (decalbright > 1) {
+            decalbright = 1;
         }
 
-        if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
-            if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
-                if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
-                    if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1))
-                        if (numdecals < max_decals - 1)
-                            numdecals++;
-
-        decalbrightness[numdecals] = decalbright;
-
-        decalposition[numdecals] = where;
-        decaltype[numdecals] = type;
-        decalopacity[numdecals] = opacity;
-        decalrotation[numdecals] = rotation;
-        decalalivetime[numdecals] = 0;
-
-        placex = (float)whichx * scale + scale;
-        placez = (float)whichy * scale;
-
-        decaltexcoords[numdecals][0][0] = (placex - where.x) / size / 2 + .5;
-        decaltexcoords[numdecals][0][1] = (placez - where.z) / size / 2 + .5;
-
-        decalvertex[numdecals][0].x = placex;
-        decalvertex[numdecals][0].z = placez;
-        decalvertex[numdecals][0].y = heightmap[whichx + 1][whichy] * scale + .01;
+        Decal decal(where, type, opacity, rotation, decalbright, whichx, whichy, size, *this, true);
 
+        if (!(decal.texcoords[0][0] < 0 && decal.texcoords[1][0] < 0 && decal.texcoords[2][0] < 0))
+            if (!(decal.texcoords[0][1] < 0 && decal.texcoords[1][1] < 0 && decal.texcoords[2][1] < 0))
+                if (!(decal.texcoords[0][0] > 1 && decal.texcoords[1][0] > 1 && decal.texcoords[2][0] > 1))
+                    if (!(decal.texcoords[0][1] > 1 && decal.texcoords[1][1] > 1 && decal.texcoords[2][1] > 1))
+                        if (decals.size() < max_decals - 1)
+                            decals.push_back(decal);
 
-        placex = (float)whichx * scale;
-        placez = (float)whichy * scale;
-
-        decaltexcoords[numdecals][1][0] = (placex - where.x) / size / 2 + .5;
-        decaltexcoords[numdecals][1][1] = (placez - where.z) / size / 2 + .5;
-
-        decalvertex[numdecals][1].x = placex;
-        decalvertex[numdecals][1].z = placez;
-        decalvertex[numdecals][1].y = heightmap[whichx][whichy] * scale + .01;
-
-
-        placex = (float)whichx * scale;
-        placez = (float)whichy * scale + scale;
-
-        decaltexcoords[numdecals][2][0] = (placex - where.x) / size / 2 + .5;
-        decaltexcoords[numdecals][2][1] = (placez - where.z) / size / 2 + .5;
-
-        decalvertex[numdecals][2].x = placex;
-        decalvertex[numdecals][2].z = placez;
-        decalvertex[numdecals][2].y = heightmap[whichx][whichy + 1] * scale + .01;
-
-        if (decalrotation[numdecals]) {
-            for (int i = 0; i < 3; i++) {
-                rot.y = 0;
-                rot.x = decaltexcoords[numdecals][i][0] - .5;
-                rot.z = decaltexcoords[numdecals][i][1] - .5;
-                rot = DoRotation(rot, 0, -decalrotation[numdecals], 0);
-                decaltexcoords[numdecals][i][0] = rot.x + .5;
-                decaltexcoords[numdecals][i][1] = rot.z + .5;
-            }
-        }
+        Decal decal2(where, type, opacity, rotation, decalbright, whichx, whichy, size, *this, false);
 
-        if (!(decaltexcoords[numdecals][0][0] < 0 && decaltexcoords[numdecals][1][0] < 0 && decaltexcoords[numdecals][2][0] < 0))
-            if (!(decaltexcoords[numdecals][0][1] < 0 && decaltexcoords[numdecals][1][1] < 0 && decaltexcoords[numdecals][2][1] < 0))
-                if (!(decaltexcoords[numdecals][0][0] > 1 && decaltexcoords[numdecals][1][0] > 1 && decaltexcoords[numdecals][2][0] > 1))
-                    if (!(decaltexcoords[numdecals][0][1] > 1 && decaltexcoords[numdecals][1][1] > 1 && decaltexcoords[numdecals][2][1] > 1))
-                        if (numdecals < max_decals - 1)
-                            numdecals++;
+        if (!(decal2.texcoords[0][0] < 0 && decal2.texcoords[1][0] < 0 && decal2.texcoords[2][0] < 0))
+            if (!(decal2.texcoords[0][1] < 0 && decal2.texcoords[1][1] < 0 && decal2.texcoords[2][1] < 0))
+                if (!(decal2.texcoords[0][0] > 1 && decal2.texcoords[1][0] > 1 && decal2.texcoords[2][0] > 1))
+                    if (!(decal2.texcoords[0][1] > 1 && decal2.texcoords[1][1] > 1 && decal2.texcoords[2][1] > 1))
+                        if (decals.size() < max_decals - 1)
+                            decals.push_back(decal2);
     }
 }
 
@@ -1498,13 +1394,5 @@ Terrain::Terrain()
 
     patch_elements = 0;
 
-    memset(decaltexcoords, 0, sizeof(decaltexcoords));
-    memset(decalvertex, 0, sizeof(decalvertex));
-    memset(decaltype, 0, sizeof(decaltype));
-    memset(decalopacity, 0, sizeof(decalopacity));
-    memset(decalrotation, 0, sizeof(decalrotation));
-    memset(decalalivetime, 0, sizeof(decalalivetime));
-    memset(decalbrightness, 0, sizeof(decalbrightness));
-    memset(decalposition, 0, sizeof(decalposition));
-    numdecals = 0;
+    decals.clear();
 }
index f6525c4b0d286777f6d00ab1c5bd4a77b3cf340c..3afaa2874d3f6371dbb973ba9c17a6d944f30ab7 100644 (file)
@@ -22,6 +22,7 @@ along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
 #define _TERRAIN_HPP_
 
 #include "Environment/Lights.hpp"
+#include "Graphic/Decal.hpp"
 #include "Graphic/gamegl.hpp"
 #include "Graphic/Texture.hpp"
 #include "Math/Frustum.hpp"
@@ -93,15 +94,7 @@ public:
 
     int patch_elements;
 
-    float decaltexcoords[max_decals][3][2];
-    XYZ decalvertex[max_decals][3];
-    int decaltype[max_decals];
-    float decalopacity[max_decals];
-    float decalrotation[max_decals];
-    float decalalivetime[max_decals];
-    float decalbrightness[max_decals];
-    XYZ decalposition[max_decals];
-    int numdecals;
+    std::vector<Decal> decals;
 
     void AddObject(XYZ where, float radius, int id);
     void DeleteDecal(int which);
@@ -118,6 +111,7 @@ public:
     void drawdecals();
     void draw(int layer);
     void DoShadows();
+    void deleteDeadDecals();
 
     Terrain();
 
index 7b195dfdcc6cc20d059c532e91fb1205baedae7f..9ceac00218bb39186a2360d65afa3499c2b44c5f 100644 (file)
@@ -67,7 +67,7 @@ extern bool devtools;
 extern int mainmenu;
 extern int bloodtoggle;
 extern int difficulty;
-extern bool decals;
+extern bool decalstoggle;
 extern float texdetail;
 extern bool musictoggle;
 extern float smoketex;
index 85224889b81343609ea219d2bd42d5a9cecd7aa5..ebf1175342ce52f5f383563c7668e8bfca5bf29e 100644 (file)
@@ -102,7 +102,7 @@ extern float envsoundlife[30];
 extern float usermousesensitivity;
 extern bool ismotionblur;
 extern bool showdamagebar; // (des)activate the damage bar
-extern bool decals;
+extern bool decalstoggle;
 extern bool skyboxtexture;
 extern float skyboxr;
 extern float skyboxg;
@@ -606,7 +606,7 @@ void Game::Loadlevel(const std::string& name, bool tutorial)
     }
 
     if (!stealthloading) {
-        terrain.numdecals = 0;
+        terrain.decals.clear();
         Sprite::deleteSprites();
 
         for (int i = 0; i < subdivision; i++) {
@@ -2458,12 +2458,7 @@ void doAttacks()
                                                     Person::players[i]->skeleton.free &&
                                                     Person::players[i]->skeleton.longdead > 1000) {
                                                 Person::players[k]->animTarget = killanim;
-                                                //TODO: refactor this out, what does it do?
-                                                for (int j = 0; j < terrain.numdecals; j++) {
-                                                    if ((terrain.decaltype[j] == blooddecal || terrain.decaltype[j] == blooddecalslow) &&
-                                                            terrain.decalalivetime[j] < 2)
-                                                        terrain.DeleteDecal(j);
-                                                }
+                                                terrain.deleteDeadDecals();
                                                 for (unsigned int l = 0; l < Object::objects.size(); l++) {
                                                     if (Object::objects[l]->model.type == decalstype)
                                                         for (int j = 0; j < Object::objects[l]->model.numdecals; j++) {
@@ -2484,12 +2479,7 @@ void doAttacks()
                                                          Person::players[i]->skeleton.free) &&
                                                         (!Person::players[i]->dead || musictype != stream_fighttheme)) {
                                                     Person::players[k]->animTarget = dropkickanim;
-                                                    for (int j = 0; j < terrain.numdecals; j++) {
-                                                        if ((terrain.decaltype[j] == blooddecal || terrain.decaltype[j] == blooddecalslow) &&
-                                                                terrain.decalalivetime[j] < 2) {
-                                                            terrain.DeleteDecal(j);
-                                                        }
-                                                    }
+                                                    terrain.deleteDeadDecals();
                                                     for (unsigned int l = 0; l < Object::objects.size(); l++) {
                                                         if (Object::objects[l]->model.type == decalstype)
                                                             for (int j = 0; j < Object::objects[l]->model.numdecals; j++) {
index 7184ce2f887d3b0021714f7fec1f997dd76d40db..bbe2df2e20b36a78647cd0ef55da87cd8970ed97 100644 (file)
@@ -33,7 +33,7 @@ float usermousesensitivity = 0;
 bool floatjump = false;
 bool cellophane = false;
 bool autoslomo = false;
-bool decals = false;
+bool decalstoggle = false;
 bool invertmouse = false;
 bool texttoggle = false;
 float blurness = 0;
diff --git a/Source/Graphic/Decal.cpp b/Source/Graphic/Decal.cpp
new file mode 100644 (file)
index 0000000..a535dee
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+Copyright (C) 2003, 2010 - Wolfire Games
+Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
+
+This file is part of Lugaru.
+
+Lugaru 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 2 of the License, or
+(at your option) any later version.
+
+Lugaru 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 Lugaru.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "Graphic/Decal.hpp"
+
+#include "Environment/Terrain.hpp"
+
+Decal::Decal() :
+    position(),
+    type(0),
+    opacity(0),
+    rotation(0),
+    alivetime(0),
+    brightness(0)
+{
+}
+
+Decal::Decal(XYZ _position, int _type, float _opacity, float _rotation, float _brightness, int whichx, int whichy, float size, const Terrain& terrain, bool first) :
+    position(_position),
+    type(_type),
+    opacity(_opacity),
+    rotation(_rotation),
+    alivetime(0),
+    brightness(_brightness)
+{
+    float placex, placez;
+    placex = (float)whichx * terrain.scale + terrain.scale;
+    placez = (float)whichy * terrain.scale;
+
+    texcoords[0][0] = (placex - position.x) / size / 2 + .5;
+    texcoords[0][1] = (placez - position.z) / size / 2 + .5;
+
+    vertex[0].x = placex;
+    vertex[0].z = placez;
+    vertex[0].y = terrain.heightmap[whichx + 1][whichy] * terrain.scale + .01;
+
+    if (first) {
+        placex = (float)whichx * terrain.scale + terrain.scale;
+        placez = (float)whichy * terrain.scale + terrain.scale;
+    } else {
+        placex = (float)whichx * terrain.scale;
+        placez = (float)whichy * terrain.scale;
+    }
+
+    texcoords[1][0] = (placex - position.x) / size / 2 + .5;
+    texcoords[1][1] = (placez - position.z) / size / 2 + .5;
+
+    vertex[1].x = placex;
+    vertex[1].z = placez;
+    if (first) {
+        vertex[1].y = terrain.heightmap[whichx + 1][whichy + 1] * terrain.scale + .01;
+    } else {
+        vertex[1].y = terrain.heightmap[whichx][whichy] * terrain.scale + .01;
+    }
+
+
+    placex = (float)whichx * terrain.scale;
+    placez = (float)whichy * terrain.scale + terrain.scale;
+
+    texcoords[2][0] = (placex - position.x) / size / 2 + .5;
+    texcoords[2][1] = (placez - position.z) / size / 2 + .5;
+
+    vertex[2].x = placex;
+    vertex[2].z = placez;
+    vertex[2].y = terrain.heightmap[whichx][whichy + 1] * terrain.scale + .01;
+
+    XYZ rot;
+    if (rotation) {
+        for (int i = 0; i < 3; i++) {
+            rot.y = 0;
+            rot.x = texcoords[i][0] - .5;
+            rot.z = texcoords[i][1] - .5;
+            rot = DoRotation(rot, 0, -rotation, 0);
+            texcoords[i][0] = rot.x + .5;
+            texcoords[i][1] = rot.z + .5;
+        }
+    }
+}
diff --git a/Source/Graphic/Decal.hpp b/Source/Graphic/Decal.hpp
new file mode 100644 (file)
index 0000000..34f2a2b
--- /dev/null
@@ -0,0 +1,45 @@
+/*
+Copyright (C) 2003, 2010 - Wolfire Games
+Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
+
+This file is part of Lugaru.
+
+Lugaru 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 2 of the License, or
+(at your option) any later version.
+
+Lugaru 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 Lugaru.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef _DECAL_HPP_
+#define _DECAL_HPP_
+
+class Terrain;
+
+#include "Math/Quaternions.hpp"
+
+class Decal
+{
+public:
+    XYZ position;
+    int type;
+    float opacity;
+    float rotation;
+    float alivetime;
+    float brightness;
+
+    float texcoords[3][2];
+    XYZ vertex[3];
+
+    Decal();
+    Decal(XYZ position, int type, float opacity, float rotation, float brightness, int whichx, int whichy, float size, const Terrain& terrain, bool first);
+};
+
+#endif
index 0c403c218bb19f1dd23bf68cb72c42107bbbbff5..ee5add1a88dde9aa6cbb3dd281c372ba300d31c7 100644 (file)
@@ -28,7 +28,7 @@ extern float viewdistance;
 extern XYZ viewer;
 extern float fadestart;
 extern float texdetail;
-extern bool decals;
+extern bool decalstoggle;
 
 int Model::LineCheck(XYZ *p1, XYZ *p2, XYZ *p, XYZ *move, float *rotate)
 {
@@ -962,7 +962,7 @@ void Model::drawdifftex(Texture texture)
 
 void Model::drawdecals(Texture shadowtexture, Texture bloodtexture, Texture bloodtexture2, Texture breaktexture)
 {
-    if (decals) {
+    if (decalstoggle) {
         if (type != decalstype)
             return;
         static int i;
@@ -1062,7 +1062,7 @@ void Model::drawdecals(Texture shadowtexture, Texture bloodtexture, Texture bloo
 
 void Model::DeleteDecal(int which)
 {
-    if (decals) {
+    if (decalstoggle) {
         if (type != decalstype)
             return;
         decaltype[which] = decaltype[numdecals - 1];
@@ -1081,7 +1081,7 @@ void Model::DeleteDecal(int which)
 
 void Model::MakeDecal(int atype, XYZ *where, float *size, float *opacity, float *rotation)
 {
-    if (decals) {
+    if (decalstoggle) {
         if (type != decalstype)
             return;
 
@@ -1159,7 +1159,7 @@ void Model::MakeDecal(int atype, XYZ *where, float *size, float *opacity, float
 
 void Model::MakeDecal(int atype, XYZ where, float size, float opacity, float rotation)
 {
-    if (decals) {
+    if (decalstoggle) {
         if (type != decalstype)
             return;
 
index 349ff67f09b1aaec96840c9ed083af5d8a3820e2..201d7dfdfc9ace84e7ab7d449280875db4969029 100644 (file)
@@ -300,7 +300,7 @@ void Menu::updateSettingsMenu()
     if (bloodtoggle == 1) setText(2, "Blood: On, low detail");
     if (bloodtoggle == 2) setText(2, "Blood: On, high detail (slower)");
     setText(4, ismotionblur ? "Blur Effects: Enabled (less compatible)" : "Blur Effects: Disabled (more compatible)");
-    setText(5, decals ? "Decals: Enabled (slower)" : "Decals: Disabled");
+    setText(5, decalstoggle ? "Decals: Enabled (slower)" : "Decals: Disabled");
     setText(6, musictoggle ? "Music: Enabled" : "Music: Disabled");
     setText(9, invertmouse ? "Invert mouse: Yes" : "Invert mouse: No");
     setText(10, std::string("Mouse Speed: ") + to_string(int(usermousesensitivity * 5)));
@@ -626,7 +626,7 @@ void Menu::Tick()
                 ismotionblur = !ismotionblur;
                 break;
             case 5:
-                decals = !decals;
+                decalstoggle = !decalstoggle;
                 break;
             case 6:
                 musictoggle = !musictoggle;
index 4ac12f55cb7b961f7e990e5a04fbb0efe441a482..5dadc8ce697e1c11d260f99bd4ddefc31644c657 100644 (file)
@@ -51,7 +51,7 @@ extern float woozy;
 extern float viewdistance;
 extern float blackout;
 extern int difficulty;
-extern bool decals;
+extern bool decalstoggle;
 extern float fadestart;
 extern bool freeze;
 extern bool winfreeze;
@@ -728,7 +728,7 @@ void Person::DoBlood(float howmuch, int which)
                     }
                 }
         }
-        if (decals) {
+        if (decalstoggle) {
             // FIXME: manipulating attributes
             bleeding = howmuch + (float)abs(Random() % 100) / 200 - .25;
             bleedxint = 0;
@@ -796,7 +796,7 @@ void Person::DoBloodBig(float howmuch, int which)
         Game::flash(.5, 0);
     }
 
-    if (bloodtoggle && decals && !Tutorial::active) {
+    if (bloodtoggle && decalstoggle && !Tutorial::active) {
         if (bleeding <= 0 && spurt) {
             spurt = 0;
             for (int i = 0; i < 3; i++) {
@@ -979,7 +979,7 @@ bool Person::DoBloodBigWhere(float howmuch, int which, XYZ where)
     float coordsx, coordsy;
     float total;
 
-    if (bloodtoggle && decals && !Tutorial::active) {
+    if (bloodtoggle && decalstoggle && !Tutorial::active) {
         where -= coords;
         if (!skeleton.free)
             where = DoRotation(where, 0, -yaw, 0);
index 49a1aa79f27f486e364ce1476fab724828dcbea2..b1970d30b792041e9c3991ff844e550cd5102068 100644 (file)
@@ -36,7 +36,7 @@ void DefaultSettings()
     fullscreen = 0;
     floatjump = 0;
     autoslomo = 1;
-    decals = 1;
+    decalstoggle = true;
     invertmouse = 0;
     bloodtoggle = 0;
     foliage = 1;
@@ -117,7 +117,7 @@ void SaveSettings()
     opstream << "\nTrilinear:\n";
     opstream << trilinear;
     opstream << "\nDecals(shadows,blood puddles,etc):\n";
-    opstream << decals;
+    opstream << decalstoggle;
     opstream << "\nInvert mouse:\n";
     opstream << invertmouse;
     opstream << "\nGamespeed:\n";
@@ -227,7 +227,7 @@ bool LoadSettings()
         } else if ( !strncmp(setting, "Trilinear", 9) ) {
             ipstream >> trilinear;
         } else if ( !strncmp(setting, "Decals", 6) ) {
-            ipstream >> decals;
+            ipstream >> decalstoggle;
         } else if ( !strncmp(setting, "Invert mouse", 12) ) {
             ipstream >> invertmouse;
         } else if ( !strncmp(setting, "Gamespeed", 9) ) {
index ca5327c0e812c64a0f569b355376f11570b35c80..d9b8886cd1b7156456dcf6628aac5b81878a4cca 100644 (file)
@@ -33,7 +33,7 @@ extern bool autoslomo;
 extern bool foliage;
 extern bool musictoggle;
 extern bool trilinear;
-extern bool decals;
+extern bool decalstoggle;
 extern bool invertmouse;
 extern float gamespeed;
 extern float oldgamespeed;