// Copyright 2021, 2022 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. #ifndef GLPLANET_SRC_MESH_H_ #define GLPLANET_SRC_MESH_H_ #include #include #include #include #include "third_party/abseil/absl/base/attributes.h" namespace glplanet { // A UV-mapped sphere. struct UvSphere { // A point on the sphere--a vector of 5-tuples (x, y, z, u, v). // // - (x, y, z) are the Cartesian coordinates of each vertex in right-handed // model space--that is, with x forward, y to the right, and z upward. // // - (u, v) are texture coordinates, with (0, 0) corresponding to the north // pole at 180 degrees of longitude. (This matches the way textures are // loaded into memory from an image in plate carree projection.) The u // coordinates are not in the range [0, 1], so you will need to set your // texture to GL_REPEAT in the s direction. struct Coordinates { float x ABSL_ATTRIBUTE_PACKED; float y ABSL_ATTRIBUTE_PACKED; float z ABSL_ATTRIBUTE_PACKED; float u ABSL_ATTRIBUTE_PACKED; float v ABSL_ATTRIBUTE_PACKED; std::string DebugString() const noexcept; }; // Creates a UV-mapped unit sphere. sectors_per_turn specifies the number of // latitude steps per 360-degree turn; slices specifies the number of vertical // slices of the sphere. These must both be at least 2; nothing less makes any // sense. // // The sphere is oriented such that the prime meridian points in the +x // direction. UvSphere(int sectors_per_turn, int slices) noexcept; // All points on the sphere. // // There are actually sectors_per_slice+1 sectors in each vertical slice of // the sphere. The extra column of vertices is necessary to ensure the last // stack has correct texture mapping. You will need to set your texture to // GL_REPEAT in the s direction for this to work properly. std::vector vertices; // The sphere's element array buffer. These elements should be drawn with // GL_TRIANGLES. std::vector elements; }; inline std::ostream& operator<<(std::ostream& out, const UvSphere::Coordinates& c) noexcept { return out << c.DebugString(); } } // namespace glplanet #endif // GLPLANET_SRC_MESH_H_