LCOV - code coverage report
Current view: top level - source/renderer - DebugRenderer.cpp (source / functions) Hit Total Coverage
Test: 0 A.D. test coverage report Lines: 0 190 0.0 %
Date: 2021-09-24 14:46:47 Functions: 0 10 0.0 %

          Line data    Source code
       1             : /* Copyright (C) 2021 Wildfire Games.
       2             :  * This file is part of 0 A.D.
       3             :  *
       4             :  * 0 A.D. is free software: you can redistribute it and/or modify
       5             :  * it under the terms of the GNU General Public License as published by
       6             :  * the Free Software Foundation, either version 2 of the License, or
       7             :  * (at your option) any later version.
       8             :  *
       9             :  * 0 A.D. is distributed in the hope that it will be useful,
      10             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      11             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      12             :  * GNU General Public License for more details.
      13             :  *
      14             :  * You should have received a copy of the GNU General Public License
      15             :  * along with 0 A.D.  If not, see <http://www.gnu.org/licenses/>.
      16             :  */
      17             : 
      18             : #include "precompiled.h"
      19             : 
      20             : #include "renderer/DebugRenderer.h"
      21             : 
      22             : #include "graphics/Camera.h"
      23             : #include "graphics/Color.h"
      24             : #include "graphics/ShaderManager.h"
      25             : #include "graphics/ShaderProgram.h"
      26             : #include "lib/ogl.h"
      27             : #include "maths/BoundingBoxAligned.h"
      28             : #include "maths/Brush.h"
      29             : #include "maths/Matrix3D.h"
      30             : #include "maths/Vector3D.h"
      31             : #include "ps/CStrInternStatic.h"
      32             : #include "renderer/Renderer.h"
      33             : 
      34             : #include <cmath>
      35             : 
      36           0 : void CDebugRenderer::DrawLine(const CVector3D& from, const CVector3D& to, const CColor& color, const float width)
      37             : {
      38           0 :     if (from == to)
      39             :         return;
      40             : 
      41           0 :     DrawLine({from, to}, color, width);
      42             : }
      43             : 
      44           0 : void CDebugRenderer::DrawLine(const std::vector<CVector3D>& line, const CColor& color, const float width)
      45             : {
      46             : #if CONFIG2_GLES
      47             :     #warning TODO: implement drawing line for GLES
      48             : #else
      49           0 :     CShaderTechniquePtr debugLineTech =
      50           0 :         g_Renderer.GetShaderManager().LoadEffect(str_debug_line);
      51           0 :     debugLineTech->BeginPass();
      52             : 
      53           0 :     CShaderProgramPtr debugLineShader = debugLineTech->GetShader();
      54           0 :     debugLineShader->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection());
      55           0 :     debugLineShader->Uniform(str_color, color);
      56             : 
      57           0 :     const CVector3D cameraIn = g_Renderer.GetViewCamera().GetOrientation().GetIn();
      58             : 
      59           0 :     std::vector<float> vertices;
      60           0 :     vertices.reserve(line.size() * 6 * 3);
      61             : #define ADD(position) \
      62             :     vertices.emplace_back((position).X); \
      63             :     vertices.emplace_back((position).Y); \
      64             :     vertices.emplace_back((position).Z);
      65             : 
      66           0 :     for (size_t idx = 1; idx < line.size(); ++idx)
      67             :     {
      68           0 :         const CVector3D from = line[idx - 1];
      69           0 :         const CVector3D to = line[idx];
      70           0 :         const CVector3D direction = (to - from).Normalized();
      71           0 :         const CVector3D view = direction.Dot(cameraIn) > 0.9f ?
      72             :             CVector3D(0.0f, 1.0f, 0.0f) :
      73           0 :             cameraIn;
      74           0 :         const CVector3D offset = view.Cross(direction).Normalized() * width;
      75             : 
      76           0 :         ADD(from + offset)
      77           0 :         ADD(to - offset)
      78           0 :         ADD(to + offset)
      79           0 :         ADD(from + offset)
      80           0 :         ADD(from - offset)
      81           0 :         ADD(to - offset)
      82             :     }
      83             : 
      84             : #undef ADD
      85             : 
      86           0 :     debugLineShader->VertexPointer(3, GL_FLOAT, 0, vertices.data());
      87           0 :     debugLineShader->AssertPointersBound();
      88           0 :     glDrawArrays(GL_TRIANGLES, 0, vertices.size() / 3);
      89             : 
      90           0 :     debugLineTech->EndPass();
      91             : #endif
      92           0 : }
      93             : 
      94           0 : void CDebugRenderer::DrawCircle(const CVector3D& origin, const float radius, const CColor& color)
      95             : {
      96             : #if CONFIG2_GLES
      97             :     #warning TODO: implement drawing circle for GLES
      98             : #else
      99           0 :     CShaderTechniquePtr debugCircleTech =
     100           0 :         g_Renderer.GetShaderManager().LoadEffect(str_debug_line);
     101           0 :     debugCircleTech->BeginPass();
     102             : 
     103           0 :     const CCamera& camera = g_Renderer.GetViewCamera();
     104             : 
     105           0 :     CShaderProgramPtr debugCircleShader = debugCircleTech->GetShader();
     106           0 :     debugCircleShader->Uniform(str_transform, camera.GetViewProjection());
     107           0 :     debugCircleShader->Uniform(str_color, color);
     108             : 
     109           0 :     const CVector3D cameraUp = camera.GetOrientation().GetUp();
     110           0 :     const CVector3D cameraLeft = camera.GetOrientation().GetLeft();
     111             : 
     112           0 :     std::vector<float> vertices;
     113             : #define ADD(position) \
     114             :     vertices.emplace_back((position).X); \
     115             :     vertices.emplace_back((position).Y); \
     116             :     vertices.emplace_back((position).Z);
     117             : 
     118           0 :     ADD(origin)
     119             : 
     120             :     constexpr size_t segments = 16;
     121           0 :     for (size_t idx = 0; idx <= segments; ++idx)
     122             :     {
     123           0 :         const float angle = M_PI * 2.0f * idx / segments;
     124           0 :         const CVector3D offset = cameraUp * sin(angle) - cameraLeft * cos(angle);
     125           0 :         ADD(origin + offset * radius)
     126             :     }
     127             : 
     128             : #undef ADD
     129             : 
     130           0 :     debugCircleShader->VertexPointer(3, GL_FLOAT, 0, vertices.data());
     131           0 :     debugCircleShader->AssertPointersBound();
     132           0 :     glDrawArrays(GL_TRIANGLE_FAN, 0, vertices.size() / 3);
     133             : 
     134           0 :     debugCircleTech->EndPass();
     135             : #endif
     136           0 : }
     137             : 
     138           0 : void CDebugRenderer::DrawCameraFrustum(const CCamera& camera, const CColor& color, int intermediates)
     139             : {
     140             : #if CONFIG2_GLES
     141             : #warning TODO: implement camera frustum for GLES
     142             : #else
     143           0 :     CCamera::Quad nearPoints;
     144           0 :     CCamera::Quad farPoints;
     145             : 
     146           0 :     camera.GetViewQuad(camera.GetNearPlane(), nearPoints);
     147           0 :     camera.GetViewQuad(camera.GetFarPlane(), farPoints);
     148           0 :     for(int i = 0; i < 4; i++)
     149             :     {
     150           0 :         nearPoints[i] = camera.m_Orientation.Transform(nearPoints[i]);
     151           0 :         farPoints[i] = camera.m_Orientation.Transform(farPoints[i]);
     152             :     }
     153             : 
     154           0 :     CShaderTechniquePtr overlayTech =
     155           0 :         g_Renderer.GetShaderManager().LoadEffect(str_debug_line);
     156           0 :     overlayTech->BeginPass();
     157             : 
     158           0 :     CShaderProgramPtr overlayShader = overlayTech->GetShader();
     159           0 :     overlayShader->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection());
     160           0 :     overlayShader->Uniform(str_color, color);
     161             : 
     162           0 :     std::vector<float> vertices;
     163             : #define ADD(position) \
     164             :     vertices.emplace_back((position).X); \
     165             :     vertices.emplace_back((position).Y); \
     166             :     vertices.emplace_back((position).Z);
     167             : 
     168             :     // Near plane.
     169           0 :     ADD(nearPoints[0]);
     170           0 :     ADD(nearPoints[1]);
     171           0 :     ADD(nearPoints[2]);
     172           0 :     ADD(nearPoints[3]);
     173             : 
     174             :     // Far plane.
     175           0 :     ADD(farPoints[0]);
     176           0 :     ADD(farPoints[1]);
     177           0 :     ADD(farPoints[2]);
     178           0 :     ADD(farPoints[3]);
     179             : 
     180             :     // Intermediate planes.
     181           0 :     CVector3D intermediatePoints[4];
     182           0 :     for(int i = 0; i < intermediates; ++i)
     183             :     {
     184           0 :         const float t = (i + 1.0f) / (intermediates + 1.0f);
     185             : 
     186           0 :         for(int j = 0; j < 4; ++j)
     187           0 :             intermediatePoints[j] = nearPoints[j] * t + farPoints[j] * (1.0f - t);
     188             : 
     189           0 :         ADD(intermediatePoints[0]);
     190           0 :         ADD(intermediatePoints[1]);
     191           0 :         ADD(intermediatePoints[2]);
     192           0 :         ADD(intermediatePoints[3]);
     193             :     }
     194             : 
     195           0 :     overlayShader->VertexPointer(3, GL_FLOAT, 0, vertices.data());
     196           0 :     overlayShader->AssertPointersBound();
     197           0 :     glDrawArrays(GL_QUADS, 0, vertices.size() / 3);
     198             : 
     199           0 :     vertices.clear();
     200             : 
     201             :     // Connection lines.
     202           0 :     ADD(nearPoints[0]);
     203           0 :     ADD(farPoints[0]);
     204           0 :     ADD(nearPoints[1]);
     205           0 :     ADD(farPoints[1]);
     206           0 :     ADD(nearPoints[2]);
     207           0 :     ADD(farPoints[2]);
     208           0 :     ADD(nearPoints[3]);
     209           0 :     ADD(farPoints[3]);
     210           0 :     ADD(nearPoints[0]);
     211           0 :     ADD(farPoints[0]);
     212             : 
     213           0 :     overlayShader->VertexPointer(3, GL_FLOAT, 0, vertices.data());
     214           0 :     overlayShader->AssertPointersBound();
     215           0 :     glDrawArrays(GL_QUAD_STRIP, 0, vertices.size() / 3);
     216             : #undef ADD
     217             : 
     218           0 :     overlayTech->EndPass();
     219             : #endif
     220           0 : }
     221             : 
     222           0 : void CDebugRenderer::DrawBoundingBox(const CBoundingBoxAligned& boundingBox, const CColor& color)
     223             : {
     224           0 :     DrawBoundingBox(boundingBox, color, g_Renderer.GetViewCamera().GetViewProjection());
     225           0 : }
     226             : 
     227           0 : void CDebugRenderer::DrawBoundingBox(const CBoundingBoxAligned& boundingBox, const CColor& color, const CMatrix3D& transform)
     228             : {
     229           0 :     CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect(str_solid);
     230           0 :     shaderTech->BeginPass();
     231             : 
     232           0 :     CShaderProgramPtr shader = shaderTech->GetShader();
     233           0 :     shader->Uniform(str_color, color);
     234           0 :     shader->Uniform(str_transform, transform);
     235             : 
     236           0 :     std::vector<float> data;
     237             : 
     238             : #define ADD_FACE(x, y, z) \
     239             :     ADD_PT(0, 0, x, y, z); ADD_PT(1, 0, x, y, z); ADD_PT(1, 1, x, y, z); \
     240             :     ADD_PT(1, 1, x, y, z); ADD_PT(0, 1, x, y, z); ADD_PT(0, 0, x, y, z);
     241             : #define ADD_PT(u_, v_, x, y, z) \
     242             :     STMT(int u = u_; int v = v_; \
     243             :         data.push_back(u); \
     244             :         data.push_back(v); \
     245             :         data.push_back(boundingBox[x].X); \
     246             :         data.push_back(boundingBox[y].Y); \
     247             :         data.push_back(boundingBox[z].Z); \
     248             :     )
     249             : 
     250           0 :     ADD_FACE(u, v, 0);
     251           0 :     ADD_FACE(0, u, v);
     252           0 :     ADD_FACE(u, 0, 1-v);
     253           0 :     ADD_FACE(u, 1-v, 1);
     254           0 :     ADD_FACE(1, u, 1-v);
     255           0 :     ADD_FACE(u, 1, v);
     256             : 
     257             : #undef ADD_FACE
     258             : 
     259           0 :     shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 5*sizeof(float), &data[0]);
     260           0 :     shader->VertexPointer(3, GL_FLOAT, 5*sizeof(float), &data[2]);
     261             : 
     262           0 :     shader->AssertPointersBound();
     263           0 :     glDrawArrays(GL_TRIANGLES, 0, 6*6);
     264             : 
     265           0 :     shaderTech->EndPass();
     266           0 : }
     267             : 
     268           0 : void CDebugRenderer::DrawBoundingBoxOutline(const CBoundingBoxAligned& boundingBox, const CColor& color)
     269             : {
     270           0 :     DrawBoundingBoxOutline(boundingBox, color, g_Renderer.GetViewCamera().GetViewProjection());
     271           0 : }
     272             : 
     273           0 : void CDebugRenderer::DrawBoundingBoxOutline(const CBoundingBoxAligned& boundingBox, const CColor& color, const CMatrix3D& transform)
     274             : {
     275           0 :     CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect(str_solid);
     276           0 :     shaderTech->BeginPass();
     277             : 
     278           0 :     CShaderProgramPtr shader = shaderTech->GetShader();
     279           0 :     shader->Uniform(str_color, color);
     280           0 :     shader->Uniform(str_transform, transform);
     281             : 
     282           0 :     std::vector<float> data;
     283             : 
     284             : #define ADD_FACE(x, y, z) \
     285             :     ADD_PT(0, 0, x, y, z); ADD_PT(1, 0, x, y, z); \
     286             :     ADD_PT(1, 0, x, y, z); ADD_PT(1, 1, x, y, z); \
     287             :     ADD_PT(1, 1, x, y, z); ADD_PT(0, 1, x, y, z); \
     288             :     ADD_PT(0, 1, x, y, z); ADD_PT(0, 0, x, y, z);
     289             : #define ADD_PT(u_, v_, x, y, z) \
     290             :     STMT(int u = u_; int v = v_; \
     291             :         data.push_back(u); \
     292             :         data.push_back(v); \
     293             :         data.push_back(boundingBox[x].X); \
     294             :         data.push_back(boundingBox[y].Y); \
     295             :         data.push_back(boundingBox[z].Z); \
     296             :     )
     297             : 
     298           0 :     ADD_FACE(u, v, 0);
     299           0 :     ADD_FACE(0, u, v);
     300           0 :     ADD_FACE(u, 0, 1-v);
     301           0 :     ADD_FACE(u, 1-v, 1);
     302           0 :     ADD_FACE(1, u, 1-v);
     303           0 :     ADD_FACE(u, 1, v);
     304             : 
     305             : #undef ADD_FACE
     306             : 
     307           0 :     shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 5*sizeof(float), &data[0]);
     308           0 :     shader->VertexPointer(3, GL_FLOAT, 5*sizeof(float), &data[2]);
     309             : 
     310           0 :     shader->AssertPointersBound();
     311           0 :     glDrawArrays(GL_LINES, 0, 6*8);
     312             : 
     313           0 :     shaderTech->EndPass();
     314           0 : }
     315             : 
     316           0 : void CDebugRenderer::DrawBrush(const CBrush& brush, const CColor& color)
     317             : {
     318           0 :     CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect(str_solid);
     319           0 :     shaderTech->BeginPass();
     320             : 
     321           0 :     CShaderProgramPtr shader = shaderTech->GetShader();
     322           0 :     shader->Uniform(str_color, color);
     323           0 :     shader->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection());
     324             : 
     325           0 :     std::vector<float> data;
     326             : 
     327           0 :     std::vector<std::vector<size_t>> faces;
     328           0 :     brush.GetFaces(faces);
     329             : 
     330             : #define ADD_VERT(a) \
     331             :     STMT( \
     332             :         data.push_back(u); \
     333             :         data.push_back(v); \
     334             :         data.push_back(brush.GetVertices()[faces[i][a]].X); \
     335             :         data.push_back(brush.GetVertices()[faces[i][a]].Y); \
     336             :         data.push_back(brush.GetVertices()[faces[i][a]].Z); \
     337             :     )
     338             : 
     339           0 :     for (size_t i = 0; i < faces.size(); ++i)
     340             :     {
     341             :         // Triangulate into (0,1,2), (0,2,3), ...
     342           0 :         for (size_t j = 1; j < faces[i].size() - 2; ++j)
     343             :         {
     344           0 :             float u = 0;
     345           0 :             float v = 0;
     346           0 :             ADD_VERT(0);
     347           0 :             ADD_VERT(j);
     348           0 :             ADD_VERT(j+1);
     349             :         }
     350             :     }
     351             : 
     352             : #undef ADD_VERT
     353             : 
     354           0 :     shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 5*sizeof(float), &data[0]);
     355           0 :     shader->VertexPointer(3, GL_FLOAT, 5*sizeof(float), &data[2]);
     356             : 
     357           0 :     shader->AssertPointersBound();
     358           0 :     glDrawArrays(GL_TRIANGLES, 0, data.size() / 5);
     359             : 
     360           0 :     shaderTech->EndPass();
     361           0 : }
     362             : 
     363           0 : void CDebugRenderer::DrawBrushOutline(const CBrush& brush, const CColor& color)
     364             : {
     365           0 :     CShaderTechniquePtr shaderTech = g_Renderer.GetShaderManager().LoadEffect(str_solid);
     366           0 :     shaderTech->BeginPass();
     367             : 
     368           0 :     CShaderProgramPtr shader = shaderTech->GetShader();
     369           0 :     shader->Uniform(str_color, color);
     370           0 :     shader->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection());
     371             : 
     372           0 :     std::vector<float> data;
     373             : 
     374           0 :     std::vector<std::vector<size_t>> faces;
     375           0 :     brush.GetFaces(faces);
     376             : 
     377             : #define ADD_VERT(a) \
     378             :     STMT( \
     379             :         data.push_back(u); \
     380             :         data.push_back(v); \
     381             :         data.push_back(brush.GetVertices()[faces[i][a]].X); \
     382             :         data.push_back(brush.GetVertices()[faces[i][a]].Y); \
     383             :         data.push_back(brush.GetVertices()[faces[i][a]].Z); \
     384             :     )
     385             : 
     386           0 :     for (size_t i = 0; i < faces.size(); ++i)
     387             :     {
     388           0 :         for (size_t j = 0; j < faces[i].size() - 1; ++j)
     389             :         {
     390           0 :             float u = 0;
     391           0 :             float v = 0;
     392           0 :             ADD_VERT(j);
     393           0 :             ADD_VERT(j+1);
     394             :         }
     395             :     }
     396             : 
     397             : #undef ADD_VERT
     398             : 
     399           0 :     shader->TexCoordPointer(GL_TEXTURE0, 2, GL_FLOAT, 5*sizeof(float), &data[0]);
     400           0 :     shader->VertexPointer(3, GL_FLOAT, 5*sizeof(float), &data[2]);
     401             : 
     402           0 :     shader->AssertPointersBound();
     403           0 :     glDrawArrays(GL_LINES, 0, data.size() / 5);
     404             : 
     405           0 :     shaderTech->EndPass();
     406           0 : }

Generated by: LCOV version 1.13