From d0e18bdb7924c71cdca8dd983711171d87ef28be Mon Sep 17 00:00:00 2001 From: Benjamin Barenblat Date: Mon, 17 Jan 2022 23:12:32 -0500 Subject: glplanet, an OpenGL-based planetary renderer MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit glplanet draws Earth like it currently appears from space, putting nighttime areas in shadow and daytime areas in light. It’s modeled after Xplanet (http://xplanet.sourceforge.net/), but whereas Xplanet is entirely a CPU-resident program, glplanet draws using OpenGL. It’s thus much less resource-intensive, particularly when using high-resolution textures. --- src/mesh_test.cc | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 src/mesh_test.cc (limited to 'src/mesh_test.cc') diff --git a/src/mesh_test.cc b/src/mesh_test.cc new file mode 100644 index 0000000..fabc84f --- /dev/null +++ b/src/mesh_test.cc @@ -0,0 +1,136 @@ +// Copyright 2021 Benjamin Barenblat +// +// Licensed under the Apache License, Version 2.0 (the "License"); you may not +// use this file except in compliance with the License. You may obtain a copy of +// the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT +// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the +// License for the specific language governing permissions and limitations under +// the License. + +#include "src/mesh.h" + +#include +#include +#include + +#include +#include + +#include "src/util.h" +#include "third_party/abseil/absl/strings/substitute.h" + +namespace glplanet { +namespace { + +using Coordinates = ::glplanet::UvSphere::Coordinates; +using ::testing::ElementsAre; +using ::testing::ExplainMatchResult; +using ::testing::Field; +using ::testing::FloatNear; +using ::testing::UnorderedElementsAre; + +struct Triangle { + uint32_t a, b, c; + + std::string DebugString() const noexcept { + return absl::Substitute("Triangle{$0, $1, $2}", a, b, c); + } +}; + +std::ostream& operator<<(std::ostream& out, const Triangle& t) noexcept { + return out << t.DebugString(); +} + +std::vector TrianglesIn(const std::vector& elements) { + DCHECK(elements.size() % 3 == 0); + std::vector result; + for (int i = 0; i < elements.size(); i += 3) { + result.push_back(Triangle{elements[i], elements[i + 1], elements[i + 2]}); + } + return result; +} + +MATCHER_P5(CoordinatesAre, xv, yv, zv, uv, vv, + absl::Substitute("is an object whose fields (x, y, z, u, v) are " + "approximately ($0, $1, $2, $3, $4)", + xv, yv, zv, uv, vv)) { + return ExplainMatchResult( + AllOf(Field("x", &Coordinates::x, FloatNear(xv, 1e-15)), + Field("y", &Coordinates::y, FloatNear(yv, 1e-15)), + Field("z", &Coordinates::z, FloatNear(zv, 1e-15)), + Field("u", &Coordinates::u, FloatNear(uv, 1e-15)), + Field("v", &Coordinates::v, FloatNear(vv, 1e-15))), + arg, result_listener); +} + +MATCHER_P3(TriangleIs, av, bv, cv, + absl::Substitute("is the triangle ($0, $1, $2)", av, bv, cv)) { + return arg.a == av && arg.b == bv && arg.c == cv; +} + +TEST(MeshTest, SmallVertices) { + // This test is overconstrained. In particular, we check the returned + // coordinates with ElementsAre, rather than UnorderedElementsAre, and the u + // coordinates are exact, rather than being normalized to [0, 1]. This allows + // us to verify that the u coordinates increase monotonically as we travel + // east around the sphere, which is important to prevent discontinuities in + // texture mapping. + UvSphere s(4, 2); + EXPECT_THAT(s.vertices, ElementsAre(CoordinatesAre(0, 0, -1, 0, 1), // + CoordinatesAre(0, 0, -1, 0.25, 1), // + CoordinatesAre(0, 0, -1, 0.5, 1), // + CoordinatesAre(0, 0, -1, 0.75, 1), // + CoordinatesAre(0, 0, -1, 1, 1), + + CoordinatesAre(-1, 0, 0, 0, 0.5), // + CoordinatesAre(0, -1, 0, 0.25, 0.5), // + CoordinatesAre(1, 0, 0, 0.5, 0.5), // + CoordinatesAre(0, 1, 0, 0.75, 0.5), // + CoordinatesAre(-1, 0, 0, 1, 0.5), + + CoordinatesAre(0, 0, 1, 0, 0), // + CoordinatesAre(0, 0, 1, 0.25, 0), // + CoordinatesAre(0, 0, 1, 0.5, 0), // + CoordinatesAre(0, 0, 1, 0.75, 0), // + CoordinatesAre(0, 0, 1, 1, 0))); +} + +TEST(MeshTest, SmallElements) { + UvSphere s(4, 2); + ASSERT_THAT(s.vertices, ElementsAre(CoordinatesAre(0, 0, -1, 0, 1), // + CoordinatesAre(0, 0, -1, 0.25, 1), // + CoordinatesAre(0, 0, -1, 0.5, 1), // + CoordinatesAre(0, 0, -1, 0.75, 1), // + CoordinatesAre(0, 0, -1, 1, 1), + + CoordinatesAre(-1, 0, 0, 0, 0.5), // + CoordinatesAre(0, -1, 0, 0.25, 0.5), // + CoordinatesAre(1, 0, 0, 0.5, 0.5), // + CoordinatesAre(0, 1, 0, 0.75, 0.5), // + CoordinatesAre(-1, 0, 0, 1, 0.5), + + CoordinatesAre(0, 0, 1, 0, 0), // + CoordinatesAre(0, 0, 1, 0.25, 0), // + CoordinatesAre(0, 0, 1, 0.5, 0), // + CoordinatesAre(0, 0, 1, 0.75, 0), // + CoordinatesAre(0, 0, 1, 1, 0))); + EXPECT_THAT( + TrianglesIn(s.elements), + UnorderedElementsAre(TriangleIs(0, 6, 5), TriangleIs(1, 6, 0), // + TriangleIs(1, 7, 6), TriangleIs(2, 7, 1), // + TriangleIs(2, 8, 7), TriangleIs(3, 8, 2), // + TriangleIs(3, 9, 8), TriangleIs(4, 9, 3), + + TriangleIs(5, 11, 10), TriangleIs(6, 11, 5), // + TriangleIs(6, 12, 11), TriangleIs(7, 12, 6), // + TriangleIs(7, 13, 12), TriangleIs(8, 13, 7), // + TriangleIs(8, 14, 13), TriangleIs(9, 14, 8))); +} + +} // namespace +} // namespace glplanet -- cgit v1.2.3