diff --git a/app/CMakeLists.txt b/app/CMakeLists.txt index 5403ac8e..dee632e0 100644 --- a/app/CMakeLists.txt +++ b/app/CMakeLists.txt @@ -126,7 +126,7 @@ alp_get_version( set_target_properties(alpineapp PROPERTIES QT_ANDROID_PACKAGE_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/android QT_ANDROID_VERSION_NAME ${ALP_VERSION} - QT_ANDROID_VERSION_CODE "${ALP_VERSION_INTEGER}000" # accidentally uploaded a high versino code to google. now there is no way back. + QT_ANDROID_VERSION_CODE "${ALP_VERSION_INTEGER}" ) target_link_libraries(alpineapp PUBLIC gl_engine Qt::Quick Qt::QuickControls2) diff --git a/app/TrackModel.cpp b/app/TrackModel.cpp index 7717c1f9..333ae2cb 100644 --- a/app/TrackModel.cpp +++ b/app/TrackModel.cpp @@ -134,8 +134,10 @@ void TrackModel::upload_track() #else const auto path = QFileDialog::getOpenFileName(nullptr, tr("Open GPX track"), "", "GPX (*.gpx *.xml)"); auto file = QFile(path); - file.open(QFile::ReadOnly); - fileContentReady(file.fileName(), file.readAll()); + if (file.open(QFile::ReadOnly)) + fileContentReady(file.fileName(), file.readAll()); + else + qDebug() << "TrackModel::upload_track: failed to read file!" << path; #endif } diff --git a/cmake/alp_add_unittest.cmake b/cmake/alp_add_unittest.cmake index a2908947..1cdcbfaa 100644 --- a/cmake/alp_add_unittest.cmake +++ b/cmake/alp_add_unittest.cmake @@ -20,7 +20,7 @@ find_package(Qt6 REQUIRED COMPONENTS Test) if (NOT TARGET Catch2) alp_add_git_repository(catch2 URL https://github.com/catchorg/Catch2.git COMMITISH v3.5.1) endif() -alp_add_git_repository(qml_catch2_console URL https://github.com/AlpineMapsOrg/qml_catch2_console.git COMMITISH fcf6dafe6c95ac5b5436b0dfe634341c3a37513a DO_NOT_ADD_SUBPROJECT) +alp_add_git_repository(qml_catch2_console URL https://github.com/AlpineMapsOrg/qml_catch2_console.git COMMITISH 33430766f7f896db523b72c76c49eeb427ee9c63 DO_NOT_ADD_SUBPROJECT) if (EMSCRIPTEN AND ALP_ENABLE_THREADING) target_compile_options(Catch2 PRIVATE -pthread) diff --git a/gl_engine/Framebuffer.cpp b/gl_engine/Framebuffer.cpp index 0e20d001..77328ddf 100644 --- a/gl_engine/Framebuffer.cpp +++ b/gl_engine/Framebuffer.cpp @@ -43,14 +43,16 @@ QOpenGLTexture::TextureFormat internal_format_qt(Framebuffer::ColourFormat f) return QOpenGLTexture::TextureFormat::RGB8_UNorm; case Framebuffer::ColourFormat::RGBA8: return QOpenGLTexture::TextureFormat::RGBA8_UNorm; + // case Framebuffer::ColourFormat::SRGBA8: + // return QOpenGLTexture::TextureFormat::SRGB8_Alpha8; case Framebuffer::ColourFormat::RG16UI: return QOpenGLTexture::TextureFormat::RG16U; - case Framebuffer::ColourFormat::Float32: - return QOpenGLTexture::TextureFormat::R32F; - case Framebuffer::ColourFormat::RGB16F: - return QOpenGLTexture::TextureFormat::RGB16F; - case Framebuffer::ColourFormat::RGBA16F: - return QOpenGLTexture::TextureFormat::RGBA16F; + // case Framebuffer::ColourFormat::Float32: + // return QOpenGLTexture::TextureFormat::R32F; + // case Framebuffer::ColourFormat::RGB16F: + // return QOpenGLTexture::TextureFormat::RGB16F; + // case Framebuffer::ColourFormat::RGBA16F: + // return QOpenGLTexture::TextureFormat::RGBA16F; case Framebuffer::ColourFormat::R32UI: return QOpenGLTexture::TextureFormat::R32U; case Framebuffer::ColourFormat::RGBA32F: @@ -69,14 +71,16 @@ GLenum format(Framebuffer::ColourFormat f) return GL_RGB; case Framebuffer::ColourFormat::RGBA8: return GL_RGBA; + // case Framebuffer::ColourFormat::SRGBA8: + // return GL_RGBA; case Framebuffer::ColourFormat::RG16UI: return QOpenGLTexture::PixelFormat::RG_Integer; - case Framebuffer::ColourFormat::Float32: // reading Float32 is inefficient, see read_colour_attachment() for details. - return GL_RED; - case Framebuffer::ColourFormat::RGB16F: - return GL_RGB; - case Framebuffer::ColourFormat::RGBA16F: - return GL_RGBA; + // case Framebuffer::ColourFormat::Float32: // reading Float32 is inefficient, see read_colour_attachment() for details. + // return GL_RED; + // case Framebuffer::ColourFormat::RGB16F: + // return GL_RGB; + // case Framebuffer::ColourFormat::RGBA16F: + // return GL_RGBA; case Framebuffer::ColourFormat::R32UI: return GL_RED_INTEGER; case Framebuffer::ColourFormat::RGBA32F: @@ -114,16 +118,17 @@ GLenum type(Framebuffer::ColourFormat f) switch (f) { case Framebuffer::ColourFormat::R8: case Framebuffer::ColourFormat::RGBA8: + // case Framebuffer::ColourFormat::SRGBA8: case Framebuffer::ColourFormat::RGB8: return GL_UNSIGNED_BYTE; case Framebuffer::ColourFormat::RG16UI: return QOpenGLTexture::PixelType::UInt16; - case Framebuffer::ColourFormat::Float32: + // case Framebuffer::ColourFormat::Float32: case Framebuffer::ColourFormat::RGBA32F: return GL_FLOAT; - case Framebuffer::ColourFormat::RGB16F: - case Framebuffer::ColourFormat::RGBA16F: - return GL_HALF_FLOAT; + // case Framebuffer::ColourFormat::RGB16F: + // case Framebuffer::ColourFormat::RGBA16F: + // return GL_HALF_FLOAT; case Framebuffer::ColourFormat::R32UI: return GL_UNSIGNED_INT; } @@ -159,8 +164,8 @@ QImage::Format qimage_format(Framebuffer::ColourFormat f) return QImage::Format_RGBA8888; case Framebuffer::ColourFormat::RGB8: return QImage::Format_RGB888; - case Framebuffer::ColourFormat::RGB16F: - return QImage::Format_RGB16; + // case Framebuffer::ColourFormat::RGB16F: + // return QImage::Format_RGB16; default: throw std::logic_error("unsupported, QImage does not support the color format of the texture"); } @@ -304,9 +309,9 @@ T Framebuffer::read_colour_attachment_pixel(unsigned int index, const glm::dvec2 case Framebuffer::ColourFormat::R8: case Framebuffer::ColourFormat::RGB8: case Framebuffer::ColourFormat::RG16UI: // unsupported on android emulator (and webassembly linux firefox?) - case Framebuffer::ColourFormat::Float32: - case Framebuffer::ColourFormat::RGB16F: - case Framebuffer::ColourFormat::RGBA16F: + // case Framebuffer::ColourFormat::Float32: + // case Framebuffer::ColourFormat::RGB16F: + // case Framebuffer::ColourFormat::RGBA16F: case Framebuffer::ColourFormat::R32UI: // fails on linux firefox // unsupported or untested. // you really should add a unit test if you move something down to the supported section @@ -314,6 +319,7 @@ T Framebuffer::read_colour_attachment_pixel(unsigned int index, const glm::dvec2 assert(false); return {}; case Framebuffer::ColourFormat::RGBA8: + // case Framebuffer::ColourFormat::SRGBA8: assert(sizeof(T) == 4); if (sizeof(T) != 4) return {}; diff --git a/gl_engine/Framebuffer.h b/gl_engine/Framebuffer.h index 79b4bad4..b63c755b 100644 --- a/gl_engine/Framebuffer.h +++ b/gl_engine/Framebuffer.h @@ -50,12 +50,13 @@ class Framebuffer R8, RGB8, RGBA8, + // SRGBA8, // not supported as a framebuffer on android RG16UI, - RGB16F, // NOT COLOR RENDERABLE ON OPENGLES - RGBA16F, // NOT COLOR RENDERABLE ON OPENGLES + // RGB16F, // NOT COLOR RENDERABLE ON OPENGLES + // RGBA16F, // NOT COLOR RENDERABLE ON OPENGLES R32UI, - Float32, // NOT COLOR RENDERABLE ON OPENGLES - RGBA32F, // NOT COLOR RENDERABLE ON OPENGLES (weirdly it works, maybe because of extension, that qt activates?) + // Float32, // NOT COLOR RENDERABLE ON OPENGLES + RGBA32F, // NOT COLOR RENDERABLE ON OPENGLES (weirdly it works, maybe because of extension, that qt activates?) }; private: diff --git a/gl_engine/Texture.cpp b/gl_engine/Texture.cpp index 50819172..3334306b 100644 --- a/gl_engine/Texture.cpp +++ b/gl_engine/Texture.cpp @@ -48,6 +48,8 @@ GlParams gl_tex_params(gl_engine::Texture::Format format) return { GLint(gl_engine::Texture::compressed_texture_format()), 0, 0, 0, 0, true }; case F::RGBA8: return { GL_RGBA8, GL_RGBA, GL_UNSIGNED_BYTE, 4, 1, true }; + case F::SRGBA8: + return { GL_SRGB8_ALPHA8, GL_RGBA, GL_UNSIGNED_BYTE, 4, 1, true }; case F::RGBA8UI: return { GL_RGBA8UI, GL_RGBA_INTEGER, GL_UNSIGNED_BYTE, 4, 1 }; case F::RGBA32F: @@ -135,12 +137,13 @@ void gl_engine::Texture::upload(const nucleus::utils::ColourTexture& texture) f->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); const auto width = GLsizei(texture.width()); const auto height = GLsizei(texture.height()); + const auto p = gl_tex_params(m_format); if (m_format == Format::CompressedRGBA8) { assert(m_min_filter != Filter::MipMapLinear); const auto format = gl_engine::Texture::compressed_texture_format(); f->glCompressedTexImage2D(GLenum(m_target), 0, format, width, height, 0, GLsizei(texture.n_bytes()), texture.data()); - } else if (m_format == Format::RGBA8) { - f->glTexImage2D(GLenum(m_target), 0, GL_RGBA8, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture.data()); + } else if (m_format == Format::RGBA8 || m_format == Format::SRGBA8) { + f->glTexImage2D(GLenum(m_target), 0, p.internal_format, width, height, 0, p.format, p.type, texture.data()); if (m_min_filter == Filter::MipMapLinear) f->glGenerateMipmap(GLenum(m_target)); } else { @@ -163,7 +166,7 @@ void gl_engine::Texture::upload(const nucleus::utils::ColourTexture& texture, un if (m_format == Format::CompressedRGBA8) { const auto format = gl_engine::Texture::compressed_texture_format(); f->glCompressedTexSubImage3D(GLenum(m_target), 0, 0, 0, GLint(array_index), width, height, 1, format, GLsizei(texture.n_bytes()), texture.data()); - } else if (m_format == Format::RGBA8) { + } else if (m_format == Format::RGBA8 || m_format == Format::SRGBA8) { f->glTexSubImage3D(GLenum(m_target), 0, 0, 0, GLint(array_index), width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE, texture.data()); } else { assert(false); @@ -188,7 +191,7 @@ void gl_engine::Texture::upload(const nucleus::utils::MipmappedColourTexture& mi const auto format = gl_engine::Texture::compressed_texture_format(); f->glCompressedTexSubImage3D( GLenum(m_target), mip_level, 0, 0, GLint(array_index), width, height, 1, format, GLsizei(texture.n_bytes()), texture.data()); - } else if (m_format == Format::RGBA8) { + } else if (m_format == Format::RGBA8 || m_format == Format::SRGBA8) { f->glTexSubImage3D(GLenum(m_target), mip_level, 0, 0, GLint(array_index), width, height, 1, GL_RGBA, GL_UNSIGNED_BYTE, texture.data()); } else { assert(false); @@ -274,18 +277,18 @@ GLenum gl_engine::Texture::compressed_texture_format() const ext = gl.getExtension("WEBGL_compressed_texture_etc"); if (ext === null) return 0; - return ext.COMPRESSED_RGB8_ETC2; + return ext.COMPRESSED_SRGB8_ETC2; }); // qDebug() << "gl_engine::Texture::compressed_texture_format: gl_texture_format from js: " << gl_texture_format; // clang-format on if (gl_texture_format == 0) { - gl_texture_format = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; // not on mobile + gl_texture_format = GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; // not on mobile } return gl_texture_format; #elif defined(__ANDROID__) - return GL_COMPRESSED_RGB8_ETC2; + return GL_COMPRESSED_SRGB8_ETC2; #else - return GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + return GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; #endif } diff --git a/gl_engine/Texture.h b/gl_engine/Texture.h index 697d1820..0632f4ac 100644 --- a/gl_engine/Texture.h +++ b/gl_engine/Texture.h @@ -33,6 +33,7 @@ class Texture { enum class Target : GLenum { _2d = GL_TEXTURE_2D, _2dArray = GL_TEXTURE_2D_ARRAY }; // no 1D textures in webgl enum class Format { RGBA8, // normalised on gpu + SRGBA8, // normalised on gpu CompressedRGBA8, // normalised on gpu, compression format depends on desktop/mobile RGBA8UI, RGBA32F, diff --git a/gl_engine/shaders/compose.frag b/gl_engine/shaders/compose.frag index fb886f34..851a3d93 100644 --- a/gl_engine/shaders/compose.frag +++ b/gl_engine/shaders/compose.frag @@ -20,6 +20,11 @@ highp float calculate_falloff(highp float dist, highp float from, highp float to return clamp(1.0 - (dist - from) / (to - from), 0.0, 1.0); } +highp float calculate_atmospheric_falloff(highp float dist, highp float camera_cos, highp float from, highp float to) { + // return clamp(1.0 - (dist - from) / (to - from), 0.0, 1.0); + return clamp(1.0 - (dist - from) / (to - from), camera_cos, 1.0); +} + #include "atmosphere_implementation.glsl" #include "encoder.glsl" #include "shared_config.glsl" @@ -157,7 +162,6 @@ void main() { highp float dist = pos_dist.w; // negative if sky // Alpha-Value for Tile-Overlay (distant linear falloff) lowp float alpha = 0.0; - if (dist > 0.0) alpha = calculate_falloff(dist, 300000.0, 600000.0); highp vec3 normal = octNormalDecode2u16(texture(texin_normal, texcoords).xy); @@ -174,8 +178,8 @@ void main() { highp vec3 pos_ws = pos_cws + origin; highp vec3 ray_direction = pos_cws / dist; highp vec4 material_light_response = conf.material_light_response; + alpha = calculate_atmospheric_falloff(dist, -ray_direction.z, 300000.0, 600000.0); - highp vec3 light_through_atmosphere = calculate_atmospheric_light(origin / 1000.0, ray_direction, dist / 1000.0, albedo, 10); highp float shadow_term = 0.0; if (bool(conf.csm_enabled)) { @@ -260,4 +264,6 @@ void main() { } } + // srgb framebuffer support is patchy. encoding manually here. + out_Color = vec4(pow(out_Color.rgb, vec3(1.0/2.2)), out_Color.a); } diff --git a/nucleus/camera/gesture.h b/nucleus/camera/gesture.h index d3f898e9..1dd03294 100644 --- a/nucleus/camera/gesture.h +++ b/nucleus/camera/gesture.h @@ -19,6 +19,7 @@ #pragma once #include +#include #include #include #include diff --git a/nucleus/map_label/setup.h b/nucleus/map_label/setup.h index d770df18..8c0efc5b 100644 --- a/nucleus/map_label/setup.h +++ b/nucleus/map_label/setup.h @@ -73,12 +73,8 @@ SchedulerHolder scheduler(TileLoadServicePtr tile_service, const tile::utils::Aa Q_UNUSED(thread); #ifdef ALP_ENABLE_THREADING -#ifdef __EMSCRIPTEN__ // make request from main thread on webassembly due to QTBUG-109396 - tile_service->moveToThread(QCoreApplication::instance()->thread()); -#else if (thread) tile_service->moveToThread(thread); -#endif if (thread) scheduler->moveToThread(thread); #endif diff --git a/nucleus/picker/PickerManager.cpp b/nucleus/picker/PickerManager.cpp index 6d761662..69fd9411 100644 --- a/nucleus/picker/PickerManager.cpp +++ b/nucleus/picker/PickerManager.cpp @@ -72,6 +72,8 @@ void PickerManager::eval_pick(uint32_t value) for (const auto& key_value : poi->attributes.asKeyValueRange()) { picked.properties[key_value.first] = key_value.second; } + if (!picked.properties.contains("ele")) + picked.properties["ele"] = std::round(poi->lat_long_alt.z); picked.properties["type"] = to_string(poi->type); picked.properties["latitude"] = poi->lat_long_alt.x; picked.properties["longitude"] = poi->lat_long_alt.y; diff --git a/nucleus/tile/setup.h b/nucleus/tile/setup.h index 7a4432cb..3348a803 100644 --- a/nucleus/tile/setup.h +++ b/nucleus/tile/setup.h @@ -75,12 +75,8 @@ inline GeometrySchedulerHolder geometry_scheduler(TileLoadServicePtr tile_servic Q_UNUSED(thread); #ifdef ALP_ENABLE_THREADING -#ifdef __EMSCRIPTEN__ // make request from main thread on webassembly due to QTBUG-109396 - tile_service->moveToThread(QCoreApplication::instance()->thread()); -#else if (thread) tile_service->moveToThread(thread); -#endif if (thread) scheduler->moveToThread(thread); #endif diff --git a/sanitizer_supressions/linux_leak.supp b/sanitizer_supressions/linux_leak.supp index fa893459..aca639ec 100644 --- a/sanitizer_supressions/linux_leak.supp +++ b/sanitizer_supressions/linux_leak.supp @@ -2,3 +2,7 @@ leak:dbus leak:fontconfig leak:icui18n leak:gallium +leak:libGLX_mesa +leak:libGLX.so +leak:qglx_findConfig +leak:Qt6Gui.so diff --git a/unittests/gl_engine/texture.cpp b/unittests/gl_engine/texture.cpp index b923c7cf..4180e3cf 100644 --- a/unittests/gl_engine/texture.cpp +++ b/unittests/gl_engine/texture.cpp @@ -291,9 +291,9 @@ TEST_CASE("gl texture") const auto g = qGreen(result_pixel); const auto b = qBlue(result_pixel); - diff += std::abs(r - ref_pixel.x) / 255.0; - diff += std::abs(g - ref_pixel.y) / 255.0; - diff += std::abs(b - ref_pixel.z) / 255.0; + diff += std::abs(r / 255.0 - std::pow(ref_pixel.x / 255.0, 2.2)); + diff += std::abs(g / 255.0 - std::pow(ref_pixel.y / 255.0, 2.2)); + diff += std::abs(b / 255.0 - std::pow(ref_pixel.z / 255.0, 2.2)); } } CAPTURE(resolution); @@ -381,7 +381,7 @@ TEST_CASE("gl texture") for (auto texture_type : texture_types) { CAPTURE(texture_type.first); CAPTURE(texture_type.second); - const auto format = (texture_type.first == ColourTexture::Format::Uncompressed_RGBA) ? gl_engine::Texture::Format::RGBA8 + const auto format = (texture_type.first == ColourTexture::Format::Uncompressed_RGBA) ? gl_engine::Texture::Format::SRGBA8 : gl_engine::Texture::Format::CompressedRGBA8; const auto use_mipmaps = texture_type.second; gl_engine::Texture opengl_texture(gl_engine::Texture::Target::_2dArray, format); @@ -433,9 +433,9 @@ TEST_CASE("gl texture") double diff = 0; for (int i = 0; i < render_result.width(); ++i) { for (int j = 0; j < render_result.height(); ++j) { - diff += std::abs(qRed(render_result.pixel(i, j)) - test_raster.pixel({ i, j }).x) / 255.0; - diff += std::abs(qGreen(render_result.pixel(i, j)) - test_raster.pixel({ i, j }).y) / 255.0; - diff += std::abs(qBlue(render_result.pixel(i, j)) - test_raster.pixel({ i, j }).z) / 255.0; + diff += std::abs(qRed(render_result.pixel(i, j)) / 255.0 - std::pow(test_raster.pixel({ i, j }).x / 255.0, 2.2)); + diff += std::abs(qGreen(render_result.pixel(i, j)) / 255.0 - std::pow(test_raster.pixel({ i, j }).y / 255.0, 2.2)); + diff += std::abs(qBlue(render_result.pixel(i, j)) / 255.0 - std::pow(test_raster.pixel({ i, j }).z / 255.0, 2.2)); } } CHECK(diff / (256 * 256 * 3) < 0.017); @@ -446,12 +446,12 @@ TEST_CASE("gl texture") double diff = 0; for (int i = 0; i < render_result.width(); ++i) { for (int j = 0; j < render_result.height(); ++j) { - diff += std::abs(qRed(render_result.pixel(i, j)) - 42) / 255.0; - diff += std::abs(qGreen(render_result.pixel(i, j)) - 142) / 255.0; - diff += std::abs(qBlue(render_result.pixel(i, j)) - 242) / 255.0; + diff += std::abs(qRed(render_result.pixel(i, j)) / 255.0 - std::pow(42 / 255.0, 2.2)); + diff += std::abs(qGreen(render_result.pixel(i, j)) / 255.0 - std::pow(142 / 255.0, 2.2)); + diff += std::abs(qBlue(render_result.pixel(i, j)) / 255.0 - std::pow(242 / 255.0, 2.2)); } } - CHECK(diff / (256 * 256 * 3) < 0.017); + CHECK(diff / (256 * 256 * 3) < 0.02); } { const QImage render_result = framebuffer.read_colour_attachment(2); @@ -459,12 +459,12 @@ TEST_CASE("gl texture") double diff = 0; for (int i = 0; i < render_result.width(); ++i) { for (int j = 0; j < render_result.height(); ++j) { - diff += std::abs(qRed(render_result.pixel(i, j)) - 222) / 255.0; - diff += std::abs(qGreen(render_result.pixel(i, j)) - 111) / 255.0; - diff += std::abs(qBlue(render_result.pixel(i, j)) - 0) / 255.0; + diff += std::abs(qRed(render_result.pixel(i, j)) / 255.0 - std::pow(222 / 255.0, 2.2)) / 255.0; + diff += std::abs(qGreen(render_result.pixel(i, j)) / 255.0 - std::pow(111 / 255.0, 2.2)) / 255.0; + diff += std::abs(qBlue(render_result.pixel(i, j)) / 255.0 - std::pow(0 / 255.0, 2.2)) / 255.0; } } - CHECK(diff / (256 * 256 * 3) < 0.017); + CHECK(diff / (256 * 256 * 3) < 0.02); } } }