diff --git a/modules/globebrowsing/rendering/clipmapglobe.cpp b/modules/globebrowsing/rendering/clipmapglobe.cpp index 5b87593773..8626e39105 100644 --- a/modules/globebrowsing/rendering/clipmapglobe.cpp +++ b/modules/globebrowsing/rendering/clipmapglobe.cpp @@ -71,10 +71,10 @@ namespace openspace { // --------- // init Renderer - auto patchRenderer = new ClipMapPatchRenderer(shared_ptr(new ClipMapGeometry(32))); - _patchRenderer.reset(patchRenderer); - auto smallestPatchRenderer = new ClipMapPatchRenderer(shared_ptr(new ClipMapGeometry(32))); - _smallestPatchRenderer.reset(smallestPatchRenderer); + auto outerPatchRenderer = new ClipMapPatchRenderer(shared_ptr(new OuterClipMapGrid(32))); + _outerPatchRenderer.reset(outerPatchRenderer); + auto innerPatchRenderer = new ClipMapPatchRenderer(shared_ptr(new InnerClipMapGrid(32))); + _innerPatchRenderer.reset(innerPatchRenderer); } ClipMapGlobe::~ClipMapGlobe() { @@ -102,10 +102,10 @@ namespace openspace { for (size_t i = minDepth; i < maxDepth; i++) { LatLon patchSize = _clipMapPyramid.getPatchSizeAtLevel(i); - _patchRenderer->renderPatch(patchSize, data, 6.3e6); + _outerPatchRenderer->renderPatch(patchSize, data, 6.3e6); } LatLon patchSize = _clipMapPyramid.getPatchSizeAtLevel(maxDepth); - _smallestPatchRenderer->renderPatch(patchSize, data, 6.3e6); + _innerPatchRenderer->renderPatch(patchSize, data, 6.3e6); } void ClipMapGlobe::update(const UpdateData& data) { diff --git a/modules/globebrowsing/rendering/clipmapglobe.h b/modules/globebrowsing/rendering/clipmapglobe.h index 093aefa256..ead63ca4cf 100644 --- a/modules/globebrowsing/rendering/clipmapglobe.h +++ b/modules/globebrowsing/rendering/clipmapglobe.h @@ -57,8 +57,8 @@ namespace openspace { void update(const UpdateData& data) override; private: - std::unique_ptr _patchRenderer; - std::unique_ptr _smallestPatchRenderer; + std::unique_ptr _outerPatchRenderer; + std::unique_ptr _innerPatchRenderer; ClipMapPyramid _clipMapPyramid; diff --git a/modules/globebrowsing/rendering/clipmapgrid.cpp b/modules/globebrowsing/rendering/clipmapgrid.cpp index 944f514cd6..42ecaeed2a 100644 --- a/modules/globebrowsing/rendering/clipmapgrid.cpp +++ b/modules/globebrowsing/rendering/clipmapgrid.cpp @@ -32,8 +32,39 @@ namespace { namespace openspace { -ClipMapGeometry::ClipMapGeometry(unsigned int resolution) +////////////////////////////////////////////////////////////////////////////////////////// +// CLIPMAP GRID (Abstract class) // +////////////////////////////////////////////////////////////////////////////////////////// + +ClipMapGrid::ClipMapGrid(unsigned int resolution) : Grid(resolution, resolution, Geometry::Positions::No, Geometry::TextureCoordinates::Yes, Geometry::Normals::No) +{ + +} + +ClipMapGrid::~ClipMapGrid() +{ + +} + +int ClipMapGrid::xResolution() const { + return resolution(); +} + +int ClipMapGrid::yResolution() const { + return resolution(); +} + +int ClipMapGrid::resolution() const { + return _xRes; +} + +////////////////////////////////////////////////////////////////////////////////////////// +// OUTER CLIPMAP GRID // +////////////////////////////////////////////////////////////////////////////////////////// + +OuterClipMapGrid::OuterClipMapGrid(unsigned int resolution) +: ClipMapGrid(resolution) { _geometry = std::unique_ptr(new Geometry( CreateElements(resolution, resolution), @@ -44,51 +75,39 @@ ClipMapGeometry::ClipMapGeometry(unsigned int resolution) _geometry->setVertexTextureCoordinates(CreateTextureCoordinates(resolution, resolution)); } -ClipMapGeometry::~ClipMapGeometry() +OuterClipMapGrid::~OuterClipMapGrid() { } -int ClipMapGeometry::xResolution() const { - return resolution(); -} - -int ClipMapGeometry::yResolution() const { - return resolution(); -} - -int ClipMapGeometry::resolution() const { - return _xRes; -} - -size_t ClipMapGeometry::numElements(int resolution) +size_t OuterClipMapGrid::numElements(int resolution) { int numElementsInTotalSquare = 6 * (resolution + 1) * (resolution + 1); int numElementsInHole = 6 * (resolution / 4 * resolution / 4); return numElementsInTotalSquare - numElementsInHole; } -size_t ClipMapGeometry::numVerticesBottom(int resolution) +size_t OuterClipMapGrid::numVerticesBottom(int resolution) { return (resolution + 1 + 2) * (resolution / 4 + 1 + 1); } -size_t ClipMapGeometry::numVerticesLeft(int resolution) +size_t OuterClipMapGrid::numVerticesLeft(int resolution) { return (resolution / 4 + 1 + 1) * (resolution / 2 + 1); } -size_t ClipMapGeometry::numVerticesRight(int resolution) +size_t OuterClipMapGrid::numVerticesRight(int resolution) { return (resolution / 4 + 1 + 1) * (resolution / 2 + 1); } -size_t ClipMapGeometry::numVerticesTop(int resolution) +size_t OuterClipMapGrid::numVerticesTop(int resolution) { return (resolution + 1 + 2) * (resolution / 4 + 1 + 1); } -size_t ClipMapGeometry::numVertices(int resolution) +size_t OuterClipMapGrid::numVertices(int resolution) { return numVerticesBottom(resolution) + numVerticesLeft(resolution) + @@ -96,7 +115,7 @@ size_t ClipMapGeometry::numVertices(int resolution) numVerticesTop(resolution); } -void ClipMapGeometry::validate(int xRes, int yRes) { +void OuterClipMapGrid::validate(int xRes, int yRes) { ghoul_assert(xRes == yRes, "Resolution must be equal in x and in y. "); @@ -107,8 +126,7 @@ void ClipMapGeometry::validate(int xRes, int yRes) { "Resolution must be a power of 2. (" << resolution << ")"); } -std::vector ClipMapGeometry::CreateElements(int xRes, int yRes) { - int hej = 0; +std::vector OuterClipMapGrid::CreateElements(int xRes, int yRes) { validate(xRes, yRes); int resolution = xRes; std::vector elements; @@ -215,7 +233,7 @@ std::vector ClipMapGeometry::CreateElements(int xRes, int yRes) { return elements; } -std::vector ClipMapGeometry::CreatePositions(int xRes, int yRes) +std::vector OuterClipMapGrid::CreatePositions(int xRes, int yRes) { validate(xRes, yRes); int resolution = xRes; @@ -237,65 +255,194 @@ std::vector ClipMapGeometry::CreatePositions(int xRes, int yRes) } -std::vector ClipMapGeometry::CreateTextureCoordinates(int xRes, int yRes){ +std::vector OuterClipMapGrid::CreateTextureCoordinates(int xRes, int yRes){ validate(xRes, yRes); int resolution = xRes; std::vector textureCoordinates; textureCoordinates.reserve(numVertices(resolution)); - // Resolution needs to be an int to compare with negative numbers - int intResolution = resolution; // Build the bottom part of the clipmap geometry - for (int y = -1; y < intResolution / 4 + 1; y++) { - for (int x = -1; x < intResolution + 2; x++) { + for (int y = -1; y < resolution / 4 + 1; y++) { + for (int x = -1; x < resolution + 2; x++) { textureCoordinates.push_back(glm::vec2( - static_cast(x) / intResolution, - static_cast(y) / intResolution)); + static_cast(x) / resolution, + static_cast(y) / resolution)); } } // Build the left part of the clipmap geometry - for (int y = intResolution / 4; y < 3 * intResolution / 4 + 1; y++) { - for (int x = -1; x < intResolution / 4 + 1; x++) { + for (int y = resolution / 4; y < 3 * resolution / 4 + 1; y++) { + for (int x = -1; x < resolution / 4 + 1; x++) { textureCoordinates.push_back(glm::vec2( - static_cast(x) / intResolution, - static_cast(y) / intResolution)); + static_cast(x) / resolution, + static_cast(y) / resolution)); } } // Build the right part of the clipmap geometry - for (int y = intResolution / 4; y < 3 * intResolution / 4 + 1; y++) { - for (int x = 3 * intResolution / 4; x < intResolution + 2; x++) { - float u = static_cast(x) / intResolution; - float v = static_cast(y) / intResolution; + for (int y = resolution / 4; y < 3 * resolution / 4 + 1; y++) { + for (int x = 3 * resolution / 4; x < resolution + 2; x++) { + float u = static_cast(x) / resolution; + float v = static_cast(y) / resolution; textureCoordinates.push_back(glm::vec2(u, v)); } } // Build the top part of the clipmap geometry - for (int y = 3 * intResolution / 4; y < intResolution + 2; y++) { - for (int x = -1; x < intResolution + 2; x++) { + for (int y = 3 * resolution / 4; y < resolution + 2; y++) { + for (int x = -1; x < resolution + 2; x++) { textureCoordinates.push_back(glm::vec2( - static_cast(x) / intResolution, - static_cast(y) / intResolution)); + static_cast(x) / resolution, + static_cast(y) / resolution)); } } return textureCoordinates; } -std::vector ClipMapGeometry::CreateNormals(int xRes, int yRes) { +std::vector OuterClipMapGrid::CreateNormals(int xRes, int yRes) { validate(xRes, yRes); int resolution = xRes; std::vector normals; normals.reserve(numVertices(resolution)); - for (unsigned int y = 0; y < resolution + 1; y++) { - for (unsigned int x = 0; x < resolution + 1; x++) { + for (int y = -1; y < resolution + 2; y++) { + for (int x = -1; x < resolution + 2; x++) { normals.push_back(glm::vec3(0, 0, 1)); } } return normals; } + +////////////////////////////////////////////////////////////////////////////////////////// +// INNER CLIPMAP GRID // +////////////////////////////////////////////////////////////////////////////////////////// + + +InnerClipMapGrid::InnerClipMapGrid(unsigned int resolution) + : ClipMapGrid(resolution) +{ + _geometry = std::unique_ptr(new Geometry( + CreateElements(resolution, resolution), + Geometry::Positions::No, + Geometry::TextureCoordinates::Yes, + Geometry::Normals::No)); + + _geometry->setVertexTextureCoordinates(CreateTextureCoordinates(resolution, resolution)); +} + +InnerClipMapGrid::~InnerClipMapGrid() +{ + +} + +size_t InnerClipMapGrid::numElements(int resolution) +{ + return resolution * resolution * 6; +} + +size_t InnerClipMapGrid::numVertices(int resolution) +{ + return (resolution + 1) * (resolution + 1); +} + +void InnerClipMapGrid::validate(int xRes, int yRes) { + + ghoul_assert(xRes == yRes, + "Resolution must be equal in x and in y. "); + int resolution = xRes; + ghoul_assert(resolution >= 1, + "Resolution must be at least 1. (" << resolution << ")"); +} + +std::vector InnerClipMapGrid::CreateElements(int xRes, int yRes) { + validate(xRes, yRes); + int resolution = xRes; + std::vector elements; + elements.reserve(numElements(resolution)); + + // x v01---v11 x .. + // | / | + // x v00---v10 x .. + // + // x x x x .. + // : : : : + + for (unsigned int y = 0; y < resolution + 2; y++) { + for (unsigned int x = 0; x < resolution + 2; x++) { + GLuint v00 = (y + 0) * (resolution + 3) + x + 0; + GLuint v10 = (y + 0) * (resolution + 3) + x + 1; + GLuint v01 = (y + 1) * (resolution + 3) + x + 0; + GLuint v11 = (y + 1) * (resolution + 3) + x + 1; + + elements.push_back(v00); + elements.push_back(v10); + elements.push_back(v11); + + elements.push_back(v00); + elements.push_back(v11); + elements.push_back(v01); + } + } + + return elements; +} + +std::vector InnerClipMapGrid::CreatePositions(int xRes, int yRes) +{ + validate(xRes, yRes); + int resolution = xRes; + std::vector positions; + positions.reserve(numVertices(resolution)); + std::vector templateTextureCoords = CreateTextureCoordinates(xRes, yRes); + + // Copy from 2d texture coordinates and use as template to create positions + for (unsigned int i = 0; i < templateTextureCoords.size(); i++) { + positions.push_back( + glm::vec4( + templateTextureCoords[i].x, + templateTextureCoords[i].y, + 0, + 1)); + } + + return positions; +} + + +std::vector InnerClipMapGrid::CreateTextureCoordinates(int xRes, int yRes) { + validate(xRes, yRes); + int resolution = xRes; + std::vector textureCoordinates; + textureCoordinates.reserve(numVertices(resolution)); + + // Build the bottom part of the clipmap geometry + for (int y = -1; y < resolution + 2; y++) { + for (int x = -1; x < resolution + 2; x++) { + textureCoordinates.push_back(glm::vec2( + static_cast(x) / resolution, + static_cast(y) / resolution)); + } + } + + return textureCoordinates; +} + +std::vector InnerClipMapGrid::CreateNormals(int xRes, int yRes) { + validate(xRes, yRes); + int resolution = xRes; + std::vector normals; + normals.reserve(numVertices(resolution)); + + for (int y = -1; y < resolution + 2; y++) { + for (int x = -1; x < resolution + 2; x++) { + normals.push_back(glm::vec3(0, 0, 1)); + } + } + + return normals; +} + + }// namespace openspace \ No newline at end of file diff --git a/modules/globebrowsing/rendering/clipmapgrid.h b/modules/globebrowsing/rendering/clipmapgrid.h index ed25505484..bb0faaac46 100644 --- a/modules/globebrowsing/rendering/clipmapgrid.h +++ b/modules/globebrowsing/rendering/clipmapgrid.h @@ -32,22 +32,38 @@ namespace openspace { -class ClipMapGeometry : public Grid +////////////////////////////////////////////////////////////////////////////////////////// +// CLIPMAP GRID (Abstract class) // +////////////////////////////////////////////////////////////////////////////////////////// + +class ClipMapGrid : public Grid { public: - ClipMapGeometry(unsigned int resolution); + ClipMapGrid(unsigned int resolution); - ~ClipMapGeometry(); + ~ClipMapGrid(); virtual int xResolution() const; virtual int yResolution() const; int resolution() const; +}; + +////////////////////////////////////////////////////////////////////////////////////////// +// OUTER CLIPMAP GRID // +////////////////////////////////////////////////////////////////////////////////////////// + +class OuterClipMapGrid : public ClipMapGrid +{ +public: + OuterClipMapGrid(unsigned int resolution); + + ~OuterClipMapGrid(); protected: - virtual std::vector CreateElements( int xRes, int yRes); - virtual std::vector CreatePositions( int xRes, int yRes); - virtual std::vector CreateTextureCoordinates( int xRes, int yRes); - virtual std::vector CreateNormals( int xRes, int yRes); + virtual std::vector CreateElements(int xRes, int yRes); + virtual std::vector CreatePositions(int xRes, int yRes); + virtual std::vector CreateTextureCoordinates(int xRes, int yRes); + virtual std::vector CreateNormals(int xRes, int yRes); private: void validate(int xRes, int yRes); @@ -60,5 +76,30 @@ private: static size_t numElements(int resolution); static size_t numVertices(int resolution); }; + +////////////////////////////////////////////////////////////////////////////////////////// +// INNER CLIPMAP GRID // +////////////////////////////////////////////////////////////////////////////////////////// + +class InnerClipMapGrid : public ClipMapGrid +{ +public: + InnerClipMapGrid(unsigned int resolution); + + ~InnerClipMapGrid(); + +protected: + virtual std::vector CreateElements(int xRes, int yRes); + virtual std::vector CreatePositions(int xRes, int yRes); + virtual std::vector CreateTextureCoordinates(int xRes, int yRes); + virtual std::vector CreateNormals(int xRes, int yRes); + +private: + void validate(int xRes, int yRes); + + static size_t numElements(int resolution); + static size_t numVertices(int resolution); +}; + } // namespace openspace #endif // __CLIPMAPGEOMETRY_H__ \ No newline at end of file diff --git a/modules/globebrowsing/rendering/patchrenderer.cpp b/modules/globebrowsing/rendering/patchrenderer.cpp index c2d0cddb5c..b33252ffb3 100644 --- a/modules/globebrowsing/rendering/patchrenderer.cpp +++ b/modules/globebrowsing/rendering/patchrenderer.cpp @@ -55,9 +55,8 @@ namespace openspace { ////////////////////////////////////////////////////////////////////////////////////// // PATCH RENDERER // ////////////////////////////////////////////////////////////////////////////////////// - PatchRenderer::PatchRenderer(shared_ptr geometry) - : _grid(geometry) - , _tileSet(LatLon(M_PI, M_PI * 2), LatLon(M_PI / 2, - M_PI), 0) + PatchRenderer::PatchRenderer() + : _tileSet(LatLon(M_PI, M_PI * 2), LatLon(M_PI / 2, -M_PI), 0) { } @@ -76,7 +75,8 @@ namespace openspace { // LATLON PATCH RENDERER // ////////////////////////////////////////////////////////////////////////////////////// LatLonPatchRenderer::LatLonPatchRenderer(shared_ptr grid) - : PatchRenderer(grid) + : PatchRenderer() + , _grid(grid) { _programObject = OsEng.renderEngine().buildRenderProgram( "LatLonSphereMappingProgram", @@ -154,8 +154,9 @@ namespace openspace { ////////////////////////////////////////////////////////////////////////////////////// // CLIPMAP PATCH RENDERER // ////////////////////////////////////////////////////////////////////////////////////// - ClipMapPatchRenderer::ClipMapPatchRenderer(shared_ptr grid) - : PatchRenderer(grid) + ClipMapPatchRenderer::ClipMapPatchRenderer(shared_ptr grid) + : PatchRenderer() + , _grid(grid) { _programObject = OsEng.renderEngine().buildRenderProgram( "LatLonSphereMappingProgram", @@ -182,7 +183,7 @@ namespace openspace { mat4 modelTransform = translate(mat4(1), data.position.vec3()); // Snap patch position - int segmentsPerPatch = 32; + int segmentsPerPatch = _grid->resolution(); LatLon stepSize = LatLon( patchSize.lat / segmentsPerPatch, patchSize.lon / segmentsPerPatch); diff --git a/modules/globebrowsing/rendering/patchrenderer.h b/modules/globebrowsing/rendering/patchrenderer.h index a7b1827f1d..28ec03718e 100644 --- a/modules/globebrowsing/rendering/patchrenderer.h +++ b/modules/globebrowsing/rendering/patchrenderer.h @@ -33,6 +33,7 @@ #include #include +#include #include #include @@ -55,14 +56,12 @@ namespace openspace { class PatchRenderer { public: - PatchRenderer(shared_ptr); + PatchRenderer(); ~PatchRenderer(); protected: unique_ptr _programObject; - shared_ptr _grid; - TextureTileSet _tileSet; }; @@ -85,18 +84,22 @@ namespace openspace { const RenderData& data, double radius, const TileIndex& ti); + private: + shared_ptr _grid; }; class ClipMapPatchRenderer : public PatchRenderer { public: - ClipMapPatchRenderer(shared_ptr grid); + ClipMapPatchRenderer(shared_ptr grid); void renderPatch( const LatLon& patchSize, const RenderData& data, double radius); + private: + shared_ptr _grid; }; } // namespace openspace