diff --git a/source/renderer/DebugRenderer.cpp b/source/renderer/DebugRenderer.cpp index c559091876..eedd085230 100644 --- a/source/renderer/DebugRenderer.cpp +++ b/source/renderer/DebugRenderer.cpp @@ -137,7 +137,7 @@ void CDebugRenderer::DrawCircle(const CVector3D& origin, const float radius, con #endif } -void CDebugRenderer::DrawCameraFrustum(const CCamera& camera, int intermediates) const +void CDebugRenderer::DrawCameraFrustum(const CCamera& camera, const CColor& color, int intermediates) const { #if CONFIG2_GLES #warning TODO: implement camera frustum for GLES @@ -153,52 +153,73 @@ void CDebugRenderer::DrawCameraFrustum(const CCamera& camera, int intermediates) farPoints[i] = camera.m_Orientation.Transform(farPoints[i]); } - // near plane - glBegin(GL_POLYGON); - glVertex3fv(&nearPoints[0].X); - glVertex3fv(&nearPoints[1].X); - glVertex3fv(&nearPoints[2].X); - glVertex3fv(&nearPoints[3].X); - glEnd(); + CShaderTechniquePtr overlayTech = + g_Renderer.GetShaderManager().LoadEffect(str_debug_line); + overlayTech->BeginPass(); + CShaderProgramPtr overlayShader = overlayTech->GetShader(); - // far plane - glBegin(GL_POLYGON); - glVertex3fv(&farPoints[0].X); - glVertex3fv(&farPoints[1].X); - glVertex3fv(&farPoints[2].X); - glVertex3fv(&farPoints[3].X); - glEnd(); + overlayShader->Bind(); + overlayShader->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection()); + overlayShader->Uniform(str_color, color); - // connection lines - glBegin(GL_QUAD_STRIP); - glVertex3fv(&nearPoints[0].X); - glVertex3fv(&farPoints[0].X); - glVertex3fv(&nearPoints[1].X); - glVertex3fv(&farPoints[1].X); - glVertex3fv(&nearPoints[2].X); - glVertex3fv(&farPoints[2].X); - glVertex3fv(&nearPoints[3].X); - glVertex3fv(&farPoints[3].X); - glVertex3fv(&nearPoints[0].X); - glVertex3fv(&farPoints[0].X); - glEnd(); + std::vector vertices; +#define ADD(position) \ + vertices.emplace_back((position).X); \ + vertices.emplace_back((position).Y); \ + vertices.emplace_back((position).Z); - // intermediate planes + // Near plane. + ADD(nearPoints[0]); + ADD(nearPoints[1]); + ADD(nearPoints[2]); + ADD(nearPoints[3]); + + // Far plane. + ADD(farPoints[0]); + ADD(farPoints[1]); + ADD(farPoints[2]); + ADD(farPoints[3]); + + // Intermediate planes. CVector3D intermediatePoints[4]; for(int i = 0; i < intermediates; ++i) { - float t = (i + 1.0f) / (intermediates + 1.0f); + const float t = (i + 1.0f) / (intermediates + 1.0f); for(int j = 0; j < 4; ++j) intermediatePoints[j] = nearPoints[j] * t + farPoints[j] * (1.0f - t); - glBegin(GL_POLYGON); - glVertex3fv(&intermediatePoints[0].X); - glVertex3fv(&intermediatePoints[1].X); - glVertex3fv(&intermediatePoints[2].X); - glVertex3fv(&intermediatePoints[3].X); - glEnd(); + ADD(intermediatePoints[0]); + ADD(intermediatePoints[1]); + ADD(intermediatePoints[2]); + ADD(intermediatePoints[3]); } + + overlayShader->VertexPointer(3, GL_FLOAT, 0, vertices.data()); + overlayShader->AssertPointersBound(); + glDrawArrays(GL_QUADS, 0, vertices.size() / 3); + + vertices.clear(); + + // Connection lines. + ADD(nearPoints[0]); + ADD(farPoints[0]); + ADD(nearPoints[1]); + ADD(farPoints[1]); + ADD(nearPoints[2]); + ADD(farPoints[2]); + ADD(nearPoints[3]); + ADD(farPoints[3]); + ADD(nearPoints[0]); + ADD(farPoints[0]); + + overlayShader->VertexPointer(3, GL_FLOAT, 0, vertices.data()); + overlayShader->AssertPointersBound(); + glDrawArrays(GL_QUAD_STRIP, 0, vertices.size() / 3); +#undef ADD + + overlayShader->Unbind(); + overlayTech->EndPass(); #endif } diff --git a/source/renderer/DebugRenderer.h b/source/renderer/DebugRenderer.h index ed13db900b..80faf29346 100644 --- a/source/renderer/DebugRenderer.h +++ b/source/renderer/DebugRenderer.h @@ -52,7 +52,7 @@ public: * @param intermediates determines how many intermediate distance planes should * be hinted at between the near and far planes */ - void DrawCameraFrustum(const CCamera& camera, int intermediates = 0) const; + void DrawCameraFrustum(const CCamera& camera, const CColor& color, int intermediates = 0) const; /** * Render the surfaces of the bound box as triangles. diff --git a/source/renderer/TerrainOverlay.cpp b/source/renderer/TerrainOverlay.cpp index 1ccfd4ebf8..3434bc00ee 100644 --- a/source/renderer/TerrainOverlay.cpp +++ b/source/renderer/TerrainOverlay.cpp @@ -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 @@ -20,6 +20,8 @@ #include "TerrainOverlay.h" #include "graphics/Color.h" +#include "graphics/ShaderManager.h" +#include "graphics/ShaderProgram.h" #include "graphics/Terrain.h" #include "lib/bits.h" #include "lib/ogl.h" @@ -182,37 +184,56 @@ void TerrainOverlay::RenderTile(const CColor& color, bool draw_hidden, ssize_t i #warning TODO: implement TerrainOverlay::RenderTile for GLES #else - glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); - CVector3D pos[2][2]; for (int di = 0; di < 2; ++di) for (int dj = 0; dj < 2; ++dj) m_Terrain->CalcPosition(i + di, j + dj, pos[di][dj]); - glBegin(GL_TRIANGLES); - glColor4fv(color.FloatArray()); - if (m_Terrain->GetTriangulationDir(i, j)) - { - glVertex3fv(pos[0][0].GetFloatArray()); - glVertex3fv(pos[1][0].GetFloatArray()); - glVertex3fv(pos[0][1].GetFloatArray()); + std::vector vertices; +#define ADD(position) \ + vertices.emplace_back((position).X); \ + vertices.emplace_back((position).Y); \ + vertices.emplace_back((position).Z); - glVertex3fv(pos[1][0].GetFloatArray()); - glVertex3fv(pos[1][1].GetFloatArray()); - glVertex3fv(pos[0][1].GetFloatArray()); - } - else - { - glVertex3fv(pos[0][0].GetFloatArray()); - glVertex3fv(pos[1][0].GetFloatArray()); - glVertex3fv(pos[1][1].GetFloatArray()); + if (m_Terrain->GetTriangulationDir(i, j)) + { + ADD(pos[0][0]); + ADD(pos[1][0]); + ADD(pos[0][1]); - glVertex3fv(pos[1][1].GetFloatArray()); - glVertex3fv(pos[0][1].GetFloatArray()); - glVertex3fv(pos[0][0].GetFloatArray()); - } - glEnd(); + ADD(pos[1][0]); + ADD(pos[1][1]); + ADD(pos[0][1]); + } + else + { + ADD(pos[0][0]); + ADD(pos[1][0]); + ADD(pos[1][1]); + ADD(pos[1][1]); + ADD(pos[0][1]); + ADD(pos[0][0]); + } +#undef ADD + + CShaderTechniquePtr overlayTech = + g_Renderer.GetShaderManager().LoadEffect(str_debug_line); + overlayTech->BeginPass(); + CShaderProgramPtr overlayShader = overlayTech->GetShader(); + + overlayShader->Bind(); + overlayShader->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection()); + overlayShader->Uniform(str_color, color); + + overlayShader->VertexPointer(3, GL_FLOAT, 0, vertices.data()); + overlayShader->AssertPointersBound(); + + glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); + glDrawArrays(GL_TRIANGLES, 0, vertices.size() / 3); + + overlayShader->Unbind(); + overlayTech->EndPass(); #endif } @@ -243,18 +264,39 @@ void TerrainOverlay::RenderTileOutline(const CColor& color, int line_width, bool if (line_width != 1) glLineWidth((float)line_width); - CVector3D pos; - glBegin(GL_QUADS); - glColor4fv(color.FloatArray()); - m_Terrain->CalcPosition(i, j, pos); glVertex3fv(pos.GetFloatArray()); - m_Terrain->CalcPosition(i+1, j, pos); glVertex3fv(pos.GetFloatArray()); - m_Terrain->CalcPosition(i+1, j+1, pos); glVertex3fv(pos.GetFloatArray()); - m_Terrain->CalcPosition(i, j+1, pos); glVertex3fv(pos.GetFloatArray()); - glEnd(); + std::vector vertices; +#define ADD(i, j) \ + m_Terrain->CalcPosition(i, j, position); \ + vertices.emplace_back(position.X); \ + vertices.emplace_back(position.Y); \ + vertices.emplace_back(position.Z); + + CVector3D position; + ADD(i, j); + ADD(i+1, j); + ADD(i+1, j+1); + ADD(i, j+1); +#undef ADD + + CShaderTechniquePtr overlayTech = + g_Renderer.GetShaderManager().LoadEffect(str_debug_line); + overlayTech->BeginPass(); + CShaderProgramPtr overlayShader = overlayTech->GetShader(); + + overlayShader->Bind(); + overlayShader->Uniform(str_transform, g_Renderer.GetViewCamera().GetViewProjection()); + overlayShader->Uniform(str_color, color); + + overlayShader->VertexPointer(3, GL_FLOAT, 0, vertices.data()); + overlayShader->AssertPointersBound(); + + glDrawArrays(GL_QUADS, 0, vertices.size() / 3); + + overlayShader->Unbind(); + overlayTech->EndPass(); if (line_width != 1) glLineWidth(1.0f); - #endif }