瀏覽代碼

Fix per-bridge fog of war visibility by using separate meshes

Co-authored-by: djeada <[email protected]>
copilot-swe-agent[bot] 1 月之前
父節點
當前提交
e52b9e6b5b
共有 2 個文件被更改,包括 57 次插入51 次删除
  1. 56 50
      render/ground/bridge_renderer.cpp
  2. 1 1
      render/ground/bridge_renderer.h

+ 56 - 50
render/ground/bridge_renderer.cpp

@@ -21,19 +21,19 @@ void BridgeRenderer::configure(const std::vector<Game::Map::Bridge> &bridges,
 }
 
 void BridgeRenderer::buildMeshes() {
+  m_meshes.clear();
+
   if (m_bridges.empty()) {
-    m_mesh.reset();
     return;
   }
 
-  std::vector<Vertex> vertices;
-  std::vector<unsigned int> indices;
-
   for (const auto &bridge : m_bridges) {
     QVector3D dir = bridge.end - bridge.start;
     float length = dir.length();
-    if (length < 0.01f)
+    if (length < 0.01f) {
+      m_meshes.push_back(nullptr);
       continue;
+    }
 
     dir.normalize();
     QVector3D perpendicular(-dir.z(), 0.0f, dir.x());
@@ -43,7 +43,8 @@ void BridgeRenderer::buildMeshes() {
         static_cast<int>(std::ceil(length / (m_tileSize * 0.3f)));
     lengthSegments = std::max(lengthSegments, 8);
 
-    unsigned int baseIndex = static_cast<unsigned int>(vertices.size());
+    std::vector<Vertex> vertices;
+    std::vector<unsigned int> indices;
 
     for (int i = 0; i <= lengthSegments; ++i) {
       float t = static_cast<float>(i) / static_cast<float>(lengthSegments);
@@ -113,7 +114,7 @@ void BridgeRenderer::buildMeshes() {
       }
 
       if (i < lengthSegments) {
-        unsigned int idx = baseIndex + i * 6;
+        unsigned int idx = i * 6;
 
         indices.push_back(idx + 0);
         indices.push_back(idx + 6);
@@ -151,18 +152,17 @@ void BridgeRenderer::buildMeshes() {
         indices.push_back(idx + 7);
       }
     }
-  }
 
-  if (vertices.empty() || indices.empty()) {
-    m_mesh.reset();
-    return;
+    if (!vertices.empty() && !indices.empty()) {
+      m_meshes.push_back(std::make_unique<Mesh>(vertices, indices));
+    } else {
+      m_meshes.push_back(nullptr);
+    }
   }
-
-  m_mesh = std::make_unique<Mesh>(vertices, indices);
 }
 
 void BridgeRenderer::submit(Renderer &renderer, ResourceManager *resources) {
-  if (!m_mesh || m_bridges.empty()) {
+  if (m_meshes.empty() || m_bridges.empty()) {
     return;
   }
 
@@ -171,18 +171,41 @@ void BridgeRenderer::submit(Renderer &renderer, ResourceManager *resources) {
   auto &visibility = Game::Map::VisibilityService::instance();
   const bool useVisibility = visibility.isInitialized();
 
-  float alpha = 1.0f;
-  QVector3D colorMultiplier(1.0f, 1.0f, 1.0f);
+  auto shader = renderer.getShader("bridge");
+  if (!shader) {
+    shader = renderer.getShader("basic");
+    if (!shader) {
+      return;
+    }
+  }
 
-  if (useVisibility) {
-    int maxVisibilityState = 0;
+  renderer.setCurrentShader(shader);
 
-    for (const auto &bridge : m_bridges) {
-      QVector3D dir = bridge.end - bridge.start;
-      float length = dir.length();
-      if (length < 0.01f)
-        continue;
+  QMatrix4x4 model;
+  model.setToIdentity();
+
+  QVector3D stoneColor(0.55f, 0.52f, 0.48f);
+
+  size_t meshIndex = 0;
+  for (const auto &bridge : m_bridges) {
+    if (meshIndex >= m_meshes.size())
+      break;
 
+    auto *mesh = m_meshes[meshIndex].get();
+    ++meshIndex;
+
+    if (!mesh) {
+      continue;
+    }
+
+    QVector3D dir = bridge.end - bridge.start;
+    float length = dir.length();
+
+    float alpha = 1.0f;
+    QVector3D colorMultiplier(1.0f, 1.0f, 1.0f);
+
+    if (useVisibility) {
+      int maxVisibilityState = 0;
       dir.normalize();
 
       int samplesPerBridge = 5;
@@ -199,38 +222,21 @@ void BridgeRenderer::submit(Renderer &renderer, ResourceManager *resources) {
         }
       }
 
-      if (maxVisibilityState == 2)
-        break;
+      if (maxVisibilityState == 0) {
+        continue;
+      } else if (maxVisibilityState == 1) {
+        alpha = 0.5f;
+        colorMultiplier = QVector3D(0.4f, 0.4f, 0.45f);
+      }
     }
 
-    if (maxVisibilityState == 0) {
-      return;
-    } else if (maxVisibilityState == 1) {
-      alpha = 0.5f;
-      colorMultiplier = QVector3D(0.4f, 0.4f, 0.45f);
-    }
-  }
+    QVector3D finalColor(stoneColor.x() * colorMultiplier.x(),
+                         stoneColor.y() * colorMultiplier.y(),
+                         stoneColor.z() * colorMultiplier.z());
 
-  auto shader = renderer.getShader("bridge");
-  if (!shader) {
-    shader = renderer.getShader("basic");
-    if (!shader) {
-      return;
-    }
+    renderer.mesh(mesh, model, finalColor, nullptr, alpha);
   }
 
-  renderer.setCurrentShader(shader);
-
-  QMatrix4x4 model;
-  model.setToIdentity();
-
-  QVector3D stoneColor(0.55f, 0.52f, 0.48f);
-  QVector3D finalColor(stoneColor.x() * colorMultiplier.x(),
-                       stoneColor.y() * colorMultiplier.y(),
-                       stoneColor.z() * colorMultiplier.z());
-
-  renderer.mesh(m_mesh.get(), model, finalColor, nullptr, alpha);
-
   renderer.setCurrentShader(nullptr);
 }
 

+ 1 - 1
render/ground/bridge_renderer.h

@@ -26,7 +26,7 @@ private:
 
   std::vector<Game::Map::Bridge> m_bridges;
   float m_tileSize = 1.0f;
-  std::unique_ptr<Mesh> m_mesh;
+  std::vector<std::unique_ptr<Mesh>> m_meshes;
 };
 
 } // namespace GL