1
0
forked from 0ad/0ad

Adds line drawing to DebugRenderer.

This was SVN commit r25314.
This commit is contained in:
Vladislav Belov 2021-04-25 20:48:44 +00:00
parent 9977c73eb6
commit e90aaf6348
11 changed files with 67 additions and 94 deletions

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2020 Wildfire Games.
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -35,22 +35,23 @@ struct SOverlayDescriptor;
/**
* Line-based overlay, with world-space coordinates, rendered in the world
* potentially behind other objects. Designed for selection circles and debug info.
* potentially behind other objects. Designed for debug info.
*/
struct SOverlayLine
{
SOverlayLine() : m_Thickness(1) { }
SOverlayLine() : m_Thickness(0.1f) { }
CColor m_Color;
std::vector<float> m_Coords; // (x, y, z) vertex coordinate triples; shape is not automatically closed
u8 m_Thickness; // in pixels
// Shape is not automatically closed.
std::vector<CVector3D> m_Coords;
// Half-width of the line, in world-space units.
float m_Thickness;
void PushCoords(const CVector3D& v) { m_Coords.emplace_back(v); }
void PushCoords(const CVector3D& v) { PushCoords(v.X, v.Y, v.Z); }
void PushCoords(const float x, const float y, const float z)
{
m_Coords.push_back(x);
m_Coords.push_back(y);
m_Coords.push_back(z);
m_Coords.emplace_back(x, y, z);
}
};

View File

@ -36,6 +36,11 @@ void CDebugRenderer::DrawLine(const CVector3D& from, const CVector3D& to, const
if (from == to)
return;
DrawLine({from, to}, color, width);
}
void CDebugRenderer::DrawLine(const std::vector<CVector3D>& line, const CColor& color, const float width)
{
#if CONFIG2_GLES
#warning TODO: implement drawing line for GLES
#else
@ -48,33 +53,37 @@ void CDebugRenderer::DrawLine(const CVector3D& from, const CVector3D& to, const
debugLineShader->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection());
debugLineShader->Uniform(str_color, color);
// Basis to set a line with the width in R^3 space.
const CVector3D direction = (to - from).Normalized();
const CVector3D upCandidate = direction.Dot(CVector3D(0.0f, 1.0f, 0.0f)) > 0.9f ?
CVector3D(1.0f, 0.0f, 0.0f) :
CVector3D(0.0f, 1.0f, 0.0f);
const CVector3D right = direction.Cross(upCandidate).Normalized();
const CVector3D up = direction.Cross(right);
const CVector3D cameraIn = g_Renderer.GetViewCamera().GetOrientation().GetIn();
std::vector<float> vertices;
const size_t splits = 3;
float angle = 0.0f;
const float step = static_cast<float>(M_PI * 2.0f / splits);
for (size_t idx = 0; idx <= splits; ++idx, angle += step)
#define ADD(position) \
vertices.emplace_back((position).X); \
vertices.emplace_back((position).Y); \
vertices.emplace_back((position).Z);
for (size_t idx = 1; idx < line.size(); ++idx)
{
const CVector3D offset = (right * std::cos(angle) + up * std::sin(angle)) * width;
const CVector3D a = from + offset;
const CVector3D b = to + offset;
vertices.emplace_back(a.X);
vertices.emplace_back(a.Y);
vertices.emplace_back(a.Z);
vertices.emplace_back(b.X);
vertices.emplace_back(b.Y);
vertices.emplace_back(b.Z);
const CVector3D from = line[idx - 1];
const CVector3D to = line[idx];
const CVector3D direction = (to - from).Normalized();
const CVector3D view = direction.Dot(cameraIn) > 0.9f ?
CVector3D(0.0f, 1.0f, 0.0f) :
cameraIn;
const CVector3D offset = view.Cross(direction).Normalized() * width;
ADD(from + offset)
ADD(to - offset)
ADD(to + offset)
ADD(from + offset)
ADD(from - offset)
ADD(to - offset)
}
debugLineShader->VertexPointer(3, GL_FLOAT, sizeof(float) * 3, vertices.data());
#undef ADD
debugLineShader->VertexPointer(3, GL_FLOAT, 0, vertices.data());
debugLineShader->AssertPointersBound();
glDrawArrays(GL_TRIANGLE_STRIP, 0, vertices.size() / 3);
glDrawArrays(GL_TRIANGLES, 0, vertices.size() / 3);
debugLineShader->Unbind();
debugLineTech->EndPass();

View File

@ -20,6 +20,8 @@
#include "graphics/ShaderProgramPtr.h"
#include <vector>
class CBoundingBoxAligned;
class CBrush;
class CCamera;
@ -36,6 +38,7 @@ public:
* Render the line in world space.
*/
void DrawLine(const CVector3D& from, const CVector3D& to, const CColor& color, const float width);
void DrawLine(const std::vector<CVector3D>& line, const CColor& color, const float width);
/**
* Render: Renders the camera's frustum in world space.

View File

@ -30,6 +30,7 @@
#include "maths/Quaternion.h"
#include "ps/Game.h"
#include "ps/Profile.h"
#include "renderer/DebugRenderer.h"
#include "renderer/Renderer.h"
#include "renderer/TexturedLineRData.h"
#include "renderer/VertexArray.h"
@ -224,8 +225,6 @@ void OverlayRenderer::Initialize()
void OverlayRenderer::Submit(SOverlayLine* line)
{
ENSURE(line->m_Coords.size() % 3 == 0);
m->lines.push_back(line);
}
@ -381,40 +380,21 @@ void OverlayRenderer::RenderOverlaysBeforeWater()
#if CONFIG2_GLES
#warning TODO: implement OverlayRenderer::RenderOverlaysBeforeWater for GLES
#else
if (g_Renderer.GetOverlayRenderMode() == WIREFRAME)
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
pglActiveTextureARB(GL_TEXTURE0);
glDisable(GL_TEXTURE_2D);
glEnable(GL_BLEND);
// Ignore z so that we draw behind terrain (but don't disable GL_DEPTH_TEST
// since we still want to write to the z buffer)
glDepthFunc(GL_ALWAYS);
for (size_t i = 0; i < m->lines.size(); ++i)
for (SOverlayLine* line : m->lines)
{
SOverlayLine* line = m->lines[i];
if (line->m_Coords.empty())
continue;
ENSURE(line->m_Coords.size() % 3 == 0);
glColor4fv(line->m_Color.FloatArray());
glLineWidth((float)line->m_Thickness);
glInterleavedArrays(GL_V3F, sizeof(float)*3, &line->m_Coords[0]);
glDrawArrays(GL_LINE_STRIP, 0, (GLsizei)line->m_Coords.size()/3);
g_Renderer.GetDebugRenderer().DrawLine(line->m_Coords, line->m_Color, static_cast<float>(line->m_Thickness));
}
glDisableClientState(GL_VERTEX_ARRAY);
glLineWidth(1.f);
glDepthFunc(GL_LEQUAL);
glDisable(GL_BLEND);
if (g_Renderer.GetOverlayRenderMode() == WIREFRAME)
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
#endif
}

View File

@ -37,6 +37,7 @@
#include "ps/Pyrogenesis.h"
#include "ps/World.h"
#include "renderer/AlphaMapCalculator.h"
#include "renderer/DebugRenderer.h"
#include "renderer/Renderer.h"
#include "renderer/TerrainRenderer.h"
#include "renderer/WaterManager.h"
@ -1121,12 +1122,7 @@ void CPatchRData::RenderOutline()
line.push_back(pos);
}
#if CONFIG2_GLES
#warning TODO: implement CPatchRData::RenderOutlines for GLES
#else
glVertexPointer(3, GL_FLOAT, sizeof(CVector3D), &line[0]);
glDrawArrays(GL_LINE_STRIP, 0, line.size());
#endif
g_Renderer.GetDebugRenderer().DrawLine(line, CColor(0.0f, 0.0f, 1.0f, 1.0f), 0.1f);
}
void CPatchRData::RenderSides(const std::vector<CPatchRData*>& patches, const CShaderProgramPtr& shader)

View File

@ -353,14 +353,8 @@ void TerrainRenderer::RenderOutlines(int cullGroup)
if (visiblePatches.empty())
return;
#if CONFIG2_GLES
#warning TODO: implement TerrainRenderer::RenderOutlines for GLES
#else
glEnableClientState(GL_VERTEX_ARRAY);
for (size_t i = 0; i < visiblePatches.size(); ++i)
visiblePatches[i]->RenderOutline();
glDisableClientState(GL_VERTEX_ARRAY);
#endif
}

View File

@ -441,7 +441,7 @@ void CCmpRallyPointRenderer::RecomputeRallyPointPath(size_t index, CmpPtr<ICmpPo
{
SOverlayLine overlayLine;
overlayLine.m_Color = CColor(1.0f, 0.0f, 0.0f, 1.0f);
overlayLine.m_Thickness = 2;
overlayLine.m_Thickness = 0.1f;
SimRender::ConstructSquareOnGround(GetSimContext(), point.X, point.Y, 0.2f, 0.2f, 1.0f, overlayLine, true);
m_DebugNodeOverlays[index].push_back(overlayLine);
}

View File

@ -670,11 +670,11 @@ void CCmpSelectable::RenderSubmit(SceneCollector& collector, const CFrustum& fru
if (cmpVisual)
{
SimRender::ConstructBoxOutline(cmpVisual->GetBounds(), *m_DebugBoundingBoxOverlay);
m_DebugBoundingBoxOverlay->m_Thickness = 2;
m_DebugBoundingBoxOverlay->m_Thickness = 0.1f;
m_DebugBoundingBoxOverlay->m_Color = CColor(1.f, 0.f, 0.f, 1.f);
SimRender::ConstructBoxOutline(cmpVisual->GetSelectionBox(), *m_DebugSelectionBoxOverlay);
m_DebugSelectionBoxOverlay->m_Thickness = 2;
m_DebugSelectionBoxOverlay->m_Thickness = 0.1f;
m_DebugSelectionBoxOverlay->m_Color = CColor(0.f, 1.f, 0.f, 1.f);
collector.Submit(m_DebugBoundingBoxOverlay);

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2020 Wildfire Games.
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -660,7 +660,7 @@ void CCmpTerritoryManager::UpdateBoundaryLines()
else
overlayNode.m_Color = CColor(1.0f, 1.0f, 1.0f, 1.0f);
overlayNode.m_Thickness = 1;
overlayNode.m_Thickness = 0.1f;
SimRender::ConstructCircleOnGround(GetSimContext(), boundaries[i].points[j].X, boundaries[i].points[j].Y, 0.1f, overlayNode, true);
m_DebugBoundaryLineNodes.push_back(overlayNode);
}

View File

@ -1,4 +1,4 @@
/* Copyright (C) 2019 Wildfire Games.
/* Copyright (C) 2021 Wildfire Games.
* This file is part of 0 A.D.
*
* 0 A.D. is free software: you can redistribute it and/or modify
@ -57,12 +57,10 @@ void SimRender::ConstructLineOnGround(const CSimContext& context, const std::vec
for (size_t i = 0; i < xz.size(); i += 2)
{
float px = xz[i];
float pz = xz[i+1];
float py = std::max(water, cmpTerrain->GetExactGroundLevel(px, pz)) + heightOffset;
overlay.m_Coords.push_back(px);
overlay.m_Coords.push_back(py);
overlay.m_Coords.push_back(pz);
const float px = xz[i];
const float pz = xz[i+1];
const float py = std::max(water, cmpTerrain->GetExactGroundLevel(px, pz)) + heightOffset;
overlay.PushCoords(px, py, pz);
}
}
@ -99,9 +97,7 @@ static void ConstructCircleOrClosedArc(
{
// Start at the center point
cy = std::max(water, cmpTerrain->GetExactGroundLevel(x, z)) + heightOffset;
overlay.m_Coords.push_back(x);
overlay.m_Coords.push_back(cy);
overlay.m_Coords.push_back(z);
overlay.PushCoords(x, cy, z);
}
for (size_t i = 0; i <= numPoints; ++i) // use '<=' so it's a closed loop
@ -110,17 +106,13 @@ static void ConstructCircleOrClosedArc(
float px = x + radius * cosf(a);
float pz = z + radius * sinf(a);
float py = std::max(water, cmpTerrain->GetExactGroundLevel(px, pz)) + heightOffset;
overlay.m_Coords.push_back(px);
overlay.m_Coords.push_back(py);
overlay.m_Coords.push_back(pz);
overlay.PushCoords(px, py, pz);
}
if (!isCircle)
{
// Return to the center point
overlay.m_Coords.push_back(x);
overlay.m_Coords.push_back(cy);
overlay.m_Coords.push_back(z);
overlay.PushCoords(x, cy, z);
}
}
@ -195,9 +187,7 @@ void SimRender::ConstructSquareOnGround(const CSimContext& context, float x, flo
float px = coords[i].first;
float pz = coords[i].second;
float py = std::max(water, cmpTerrain->GetExactGroundLevel(px, pz)) + heightOffset;
overlay.m_Coords.push_back(px);
overlay.m_Coords.push_back(py);
overlay.m_Coords.push_back(pz);
overlay.PushCoords(px, py, pz);
}
}
@ -326,9 +316,9 @@ void SimRender::ConstructAxesMarker(const CMatrix3D& coordSystem, SOverlayLine&
outY.m_Color = CColor(0, 1, 0, .5f); // Y axis; green
outZ.m_Color = CColor(0, 0, 1, .5f); // Z axis; blue
outX.m_Thickness = 2;
outY.m_Thickness = 2;
outZ.m_Thickness = 2;
outX.m_Thickness = 0.1f;
outY.m_Thickness = 0.1f;
outZ.m_Thickness = 0.1f;
CVector3D origin = coordSystem.GetTranslation();
outX.PushCoords(origin);

View File

@ -130,7 +130,7 @@ public:
if (SelectionBoxEnabled)
{
SelectionBoxOverlay.m_Color = CColor(35/255.f, 86/255.f, 188/255.f, .75f); // pretty blue
SelectionBoxOverlay.m_Thickness = 2;
SelectionBoxOverlay.m_Thickness = 0.1f;
SimRender::ConstructBoxOutline(cmpVisual->GetSelectionBox(), SelectionBoxOverlay);
c->Submit(&SelectionBoxOverlay);