[Drape] Remove GL ES2 Support #10256
176 changed files with 4018 additions and 1850 deletions
8
.github/workflows/linux-check.yaml
vendored
8
.github/workflows/linux-check.yaml
vendored
|
@ -61,6 +61,10 @@ jobs:
|
|||
libgl1-mesa-dev \
|
||||
libglvnd-dev \
|
||||
libharfbuzz-dev \
|
||||
libxrandr-dev \
|
||||
libxinerama-dev \
|
||||
libxcursor-dev \
|
||||
libxi-dev \
|
||||
qt6-base-dev \
|
||||
libqt6svg6-dev \
|
||||
qt6-positioning-dev \
|
||||
|
@ -128,6 +132,10 @@ jobs:
|
|||
libgl1-mesa-dev \
|
||||
libglvnd-dev \
|
||||
libharfbuzz-dev \
|
||||
libxrandr-dev \
|
||||
libxinerama-dev \
|
||||
libxcursor-dev \
|
||||
libxi-dev \
|
||||
qt6-base-dev \
|
||||
libqt6svg6-dev \
|
||||
qt6-positioning-dev \
|
||||
|
|
9
.gitmodules
vendored
9
.gitmodules
vendored
|
@ -59,3 +59,12 @@
|
|||
[submodule "3party/utfcpp"]
|
||||
path = 3party/utfcpp
|
||||
url = https://github.com/nemtrif/utfcpp.git
|
||||
[submodule "3party/glfw"]
|
||||
path = 3party/glfw
|
||||
url = https://github.com/glfw/glfw.git
|
||||
[submodule "3party/CMake-MetalShaderSupport"]
|
||||
path = 3party/CMake-MetalShaderSupport
|
||||
url = https://github.com/dpogue/CMake-MetalShaderSupport.git
|
||||
[submodule "3party/imgui/imgui"]
|
||||
path = 3party/imgui/imgui
|
||||
url = https://github.com/ocornut/imgui
|
||||
|
|
1
3party/CMake-MetalShaderSupport
Submodule
1
3party/CMake-MetalShaderSupport
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 989857d2e5e54869c35ad06fb21a67d12a2dbc67
|
|
@ -66,4 +66,19 @@ add_subdirectory(vulkan_wrapper)
|
|||
|
||||
if (PLATFORM_DESKTOP)
|
||||
add_subdirectory(libtess2)
|
||||
|
||||
set(GLFW_BUILD_DOCS OFF CACHE BOOL "")
|
||||
set(GLFW_BUILD_EXAMPLES OFF CACHE BOOL "")
|
||||
set(GLFW_BUILD_TESTS OFF CACHE BOOL "")
|
||||
set(GLFW_INSTALL OFF CACHE BOOL "")
|
||||
set(GLFW_VULKAN_STATIC OFF CACHE BOOL "")
|
||||
set(GLFW_BUILD_WAYLAND OFF CACHE BOOL "")
|
||||
# Disable ARC for glfw and re-enable after it because it's globally set in the root CMakeLists.txt
|
||||
set(CMAKE_OBJC_FLAGS "")
|
||||
add_subdirectory(glfw)
|
||||
set_target_properties(glfw PROPERTIES UNITY_BUILD OFF)
|
||||
set_target_properties(glfw PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC NO)
|
||||
set(CMAKE_OBJC_FLAGS -fobjc-arc)
|
||||
|
||||
add_subdirectory(imgui)
|
||||
endif()
|
||||
|
|
1
3party/glfw
Submodule
1
3party/glfw
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 21fea01161e0d6b70c0c5c1f52dc8e7a7df14a50
|
16
3party/imgui/CMakeLists.txt
Normal file
16
3party/imgui/CMakeLists.txt
Normal file
|
@ -0,0 +1,16 @@
|
|||
project(imgui)
|
||||
|
||||
set(SRC
|
||||
imgui/imgui_draw.cpp
|
||||
imgui/imgui_tables.cpp
|
||||
imgui/imgui_widgets.cpp
|
||||
imgui/imgui.cpp
|
||||
imgui/backends/imgui_impl_glfw.cpp
|
||||
)
|
||||
|
||||
add_library(${PROJECT_NAME} ${SRC})
|
||||
target_include_directories(${PROJECT_NAME}
|
||||
PRIVATE ${OMIM_ROOT}/3party/glfw/include
|
||||
PUBLIC ${OMIM_ROOT}/3party/imgui/imgui
|
||||
PUBLIC .
|
||||
)
|
1
3party/imgui/imgui
Submodule
1
3party/imgui/imgui
Submodule
|
@ -0,0 +1 @@
|
|||
Subproject commit 6982ce43f5b143c5dce5fab0ce07dd4867b705ae
|
|
@ -90,6 +90,19 @@ else()
|
|||
message(FATAL_ERROR "Unsupported platform: ${CMAKE_SYSTEM_NAME}")
|
||||
endif()
|
||||
|
||||
if(${PLATFORM_MAC})
|
||||
set(XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES)
|
||||
|
||||
# Metal language support
|
||||
list(APPEND CMAKE_MODULE_PATH ${OMIM_ROOT}/3party/CMake-MetalShaderSupport/cmake)
|
||||
include(CheckLanguage)
|
||||
include(MetalShaderSupport)
|
||||
check_language(Metal)
|
||||
if(CMAKE_Metal_COMPILER)
|
||||
enable_language(Metal)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
# Sanitizer
|
||||
if (PLATFORM_DESKTOP)
|
||||
# https://clang.llvm.org/docs/UsersManual.html#controlling-code-generation
|
||||
|
@ -394,6 +407,7 @@ if (PLATFORM_DESKTOP)
|
|||
add_subdirectory(qt)
|
||||
omim_add_tool_subdirectory(skin_generator)
|
||||
endif()
|
||||
add_subdirectory(dev_sandbox)
|
||||
endif()
|
||||
|
||||
omim_add_test_subdirectory(qt_tstfrm)
|
||||
|
|
|
@ -224,8 +224,7 @@ bool Framework::CreateDrapeEngine(JNIEnv * env, jobject jSurface, int densityDpi
|
|||
LOG(LWARNING, ("Invalid GL context."));
|
||||
return false;
|
||||
}
|
||||
p.m_apiVersion = oglFactory->IsSupportedOpenGLES3() ? dp::ApiVersion::OpenGLES3 :
|
||||
dp::ApiVersion::OpenGLES2;
|
||||
p.m_apiVersion = dp::ApiVersion::OpenGLES3;
|
||||
p.m_surfaceWidth = oglFactory->GetWidth();
|
||||
p.m_surfaceHeight = oglFactory->GetHeight();
|
||||
|
||||
|
|
|
@ -8,20 +8,16 @@
|
|||
namespace android
|
||||
{
|
||||
|
||||
static EGLint * getContextAttributesList(bool supportedES3)
|
||||
static EGLint * getContextAttributesList()
|
||||
{
|
||||
static EGLint contextAttrList[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 2,
|
||||
EGL_NONE
|
||||
};
|
||||
static EGLint contextAttrListES3[] = {
|
||||
EGL_CONTEXT_CLIENT_VERSION, 3,
|
||||
EGL_NONE
|
||||
};
|
||||
return supportedES3 ? contextAttrListES3 : contextAttrList;
|
||||
return contextAttrList;
|
||||
}
|
||||
|
||||
AndroidOGLContext::AndroidOGLContext(bool supportedES3, EGLDisplay display, EGLSurface surface,
|
||||
AndroidOGLContext::AndroidOGLContext(EGLDisplay display, EGLSurface surface,
|
||||
EGLConfig config, AndroidOGLContext * contextToShareWith)
|
||||
: m_nativeContext(EGL_NO_CONTEXT)
|
||||
, m_surface(surface)
|
||||
|
@ -32,7 +28,7 @@ AndroidOGLContext::AndroidOGLContext(bool supportedES3, EGLDisplay display, EGLS
|
|||
ASSERT(m_display != EGL_NO_DISPLAY, ());
|
||||
|
||||
EGLContext sharedContext = (contextToShareWith == NULL) ? EGL_NO_CONTEXT : contextToShareWith->m_nativeContext;
|
||||
m_nativeContext = eglCreateContext(m_display, config, sharedContext, getContextAttributesList(supportedES3));
|
||||
m_nativeContext = eglCreateContext(m_display, config, sharedContext, getContextAttributesList());
|
||||
CHECK(m_nativeContext != EGL_NO_CONTEXT, ());
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace android
|
|||
class AndroidOGLContext : public dp::OGLContext
|
||||
{
|
||||
public:
|
||||
AndroidOGLContext(bool supportedES3, EGLDisplay display, EGLSurface surface,
|
||||
AndroidOGLContext(EGLDisplay display, EGLSurface surface,
|
||||
EGLConfig config, AndroidOGLContext * contextToShareWith);
|
||||
~AndroidOGLContext();
|
||||
|
||||
|
|
|
@ -16,26 +16,13 @@
|
|||
|
||||
#define EGL_OPENGL_ES3_BIT 0x00000040
|
||||
|
||||
int constexpr kMinSdkVersionForES3 = 21;
|
||||
|
||||
namespace android
|
||||
{
|
||||
namespace
|
||||
{
|
||||
static EGLint * getConfigAttributesListRGB8(bool supportedES3)
|
||||
static EGLint * getConfigAttributesListRGB8()
|
||||
{
|
||||
static EGLint attr_list[] = {
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
EGL_ALPHA_SIZE, 0,
|
||||
EGL_STENCIL_SIZE, 0,
|
||||
EGL_DEPTH_SIZE, 16,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
static EGLint attr_list_es3[] = {
|
||||
EGL_RED_SIZE, 8,
|
||||
EGL_GREEN_SIZE, 8,
|
||||
EGL_BLUE_SIZE, 8,
|
||||
|
@ -46,33 +33,16 @@ static EGLint * getConfigAttributesListRGB8(bool supportedES3)
|
|||
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
return supportedES3 ? attr_list_es3 : attr_list;
|
||||
return attr_list;
|
||||
}
|
||||
|
||||
int const kMaxConfigCount = 40;
|
||||
|
||||
static EGLint * getConfigAttributesListR5G6B5()
|
||||
{
|
||||
// We do not support OpenGL ES3 for R5G6B5, because some Android devices
|
||||
// are not able to create OpenGL context in such mode.
|
||||
static EGLint attr_list[] = {
|
||||
EGL_RED_SIZE, 5,
|
||||
EGL_GREEN_SIZE, 6,
|
||||
EGL_BLUE_SIZE, 5,
|
||||
EGL_STENCIL_SIZE, 0,
|
||||
EGL_DEPTH_SIZE, 16,
|
||||
EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
|
||||
EGL_SURFACE_TYPE, EGL_PBUFFER_BIT | EGL_WINDOW_BIT,
|
||||
EGL_NONE
|
||||
};
|
||||
return attr_list;
|
||||
}
|
||||
|
||||
bool IsSupportedRGB8(EGLDisplay display, bool es3)
|
||||
bool IsSupportedRGB8(EGLDisplay display)
|
||||
{
|
||||
EGLConfig configs[kMaxConfigCount];
|
||||
int count = 0;
|
||||
return eglChooseConfig(display, getConfigAttributesListRGB8(es3), configs,
|
||||
return eglChooseConfig(display, getConfigAttributesListRGB8(), configs,
|
||||
kMaxConfigCount, &count) == EGL_TRUE && count != 0;
|
||||
}
|
||||
|
||||
|
@ -90,7 +60,6 @@ AndroidOGLContextFactory::AndroidOGLContextFactory(JNIEnv * env, jobject jsurfac
|
|||
, m_surfaceWidth(0)
|
||||
, m_surfaceHeight(0)
|
||||
, m_windowSurfaceValid(false)
|
||||
, m_supportedES3(false)
|
||||
{
|
||||
m_display = eglGetDisplay(EGL_DEFAULT_DISPLAY);
|
||||
if (m_display == EGL_NO_DISPLAY)
|
||||
|
@ -106,10 +75,7 @@ AndroidOGLContextFactory::AndroidOGLContextFactory(JNIEnv * env, jobject jsurfac
|
|||
return;
|
||||
}
|
||||
|
||||
// Check ES3 availability.
|
||||
bool const isES3Supported = IsSupportedRGB8(m_display, true /* es3 */) &&
|
||||
android_get_device_api_level() >= kMinSdkVersionForES3;
|
||||
m_supportedES3 = isES3Supported && gl3stubInit();
|
||||
CHECK(gl3stubInit(), ("Could not initialize OpenGL ES3"));
|
||||
|
||||
SetSurface(env, jsurface);
|
||||
|
||||
|
@ -266,7 +232,7 @@ dp::GraphicsContext * AndroidOGLContextFactory::GetDrawContext()
|
|||
ASSERT(m_windowSurface != EGL_NO_SURFACE, ());
|
||||
if (m_drawContext == nullptr)
|
||||
{
|
||||
m_drawContext = new AndroidOGLContext(m_supportedES3, m_display, m_windowSurface,
|
||||
m_drawContext = new AndroidOGLContext(m_display, m_windowSurface,
|
||||
m_config, m_uploadContext);
|
||||
}
|
||||
return m_drawContext;
|
||||
|
@ -278,7 +244,7 @@ dp::GraphicsContext * AndroidOGLContextFactory::GetResourcesUploadContext()
|
|||
ASSERT(m_pixelbufferSurface != EGL_NO_SURFACE, ());
|
||||
if (m_uploadContext == nullptr)
|
||||
{
|
||||
m_uploadContext = new AndroidOGLContext(m_supportedES3, m_display, m_pixelbufferSurface,
|
||||
m_uploadContext = new AndroidOGLContext(m_display, m_pixelbufferSurface,
|
||||
m_config, m_drawContext);
|
||||
}
|
||||
return m_uploadContext;
|
||||
|
@ -322,17 +288,15 @@ bool AndroidOGLContextFactory::CreateWindowSurface()
|
|||
{
|
||||
EGLConfig configs[kMaxConfigCount];
|
||||
int count = 0;
|
||||
if (eglChooseConfig(m_display, getConfigAttributesListRGB8(m_supportedES3), configs,
|
||||
kMaxConfigCount, &count) != EGL_TRUE)
|
||||
if (eglChooseConfig(m_display, getConfigAttributesListRGB8(), configs,
|
||||
kMaxConfigCount, &count) == EGL_TRUE)
|
||||
{
|
||||
ASSERT(!m_supportedES3, ());
|
||||
VERIFY(eglChooseConfig(m_display, getConfigAttributesListR5G6B5(), configs,
|
||||
kMaxConfigCount, &count) == EGL_TRUE, ());
|
||||
LOG(LDEBUG, ("Backbuffer format: R5G6B5"));
|
||||
CHECK(IsSupportedRGB8(m_display), ("RGB8 is not suported on this device"));
|
||||
LOG(LDEBUG, ("Backbuffer format: RGB8"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LDEBUG, ("Backbuffer format: RGB8"));
|
||||
CHECK(false, ("OpenGL ES3 is not supported"));
|
||||
}
|
||||
ASSERT(count > 0, ("Didn't find any configs."));
|
||||
|
||||
|
|
|
@ -33,8 +33,6 @@ public:
|
|||
int GetHeight() const;
|
||||
void UpdateSurfaceSize(int w, int h);
|
||||
|
||||
bool IsSupportedOpenGLES3() const { return m_supportedES3; }
|
||||
|
||||
private:
|
||||
bool QuerySurfaceSize();
|
||||
|
||||
|
@ -56,7 +54,6 @@ private:
|
|||
int m_surfaceHeight;
|
||||
|
||||
bool m_windowSurfaceValid;
|
||||
bool m_supportedES3;
|
||||
|
||||
bool m_isInitialized = false;
|
||||
size_t m_initializationCounter = 0;
|
||||
|
|
|
@ -155,6 +155,12 @@
|
|||
<li><a href="https://chromium.googlesource.com/chromium/src/courgette/">Chromium's Courgette</a>;
|
||||
<a href="#bsd3-license" class="license">BSD License</a></li>
|
||||
|
||||
<li><a href="https://github.com/dpogue/CMake-MetalShaderSupport">CMake Metal support files</a><br>
|
||||
© 2024 Darryl Pogue and Contributors;<a href="#cmake-support-license" class="license">License</a></li>
|
||||
|
||||
<li><a href="https://github.com/ocornut/imgui">Dear ImGui</a><br>
|
||||
© 2014-2025 Omar Cornut; <a href="#mit-license" class="license">MIT License</a></li>
|
||||
|
||||
<li><a href="https://libexpat.github.io">Expat</a><br>© 1998–2000 Thai Open Source Software Center Ltd and Clark Cooper,
|
||||
© 2001–2019 Expat maintainers; <a href="#mit-license" class="license">MIT License</a></li>
|
||||
|
||||
|
@ -164,6 +170,9 @@
|
|||
<li><a href="http://www.freetype.org">FreeType</a><br>
|
||||
© 2013 The FreeType Project; <a href="#freetype-license" class="license">FTL</a></li>
|
||||
|
||||
<li><a href="https://www.glfw.org/">GLFW</a><br>
|
||||
© 2002-2006 Marcus Geelnard;2006-2019 Camilla Löwy; <a href="#zlib-license" class="license">Zlib License</a></li>
|
||||
|
||||
<li><a href="http://www.g-truc.net/project-0016.html">GLM</a><br>
|
||||
© 2005–2014 G-Truc Creation; <a href="#mit-license" class="license">MIT License</a></li>
|
||||
|
||||
|
@ -1058,6 +1067,54 @@ of the copyright holder.</p>
|
|||
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
|
||||
<h2 id="cmake-support-license">CMake Metal support files</h2>
|
||||
<p>Copyright 2024 Darryl Pogue and Contributors</p>
|
||||
<p>All rights reserved.</p>
|
||||
|
||||
<p>Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:</p>
|
||||
|
||||
<p>* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.</p>
|
||||
|
||||
<p>* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.</p>
|
||||
|
||||
<p>* Neither the name of Kitware, Inc. nor the names of Contributors may be used to endorse or promote products derived from this software without specific prior written permission.</p>
|
||||
|
||||
<p>THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.</p>
|
||||
|
||||
<p>------------------------------------------------------------------------------</p>
|
||||
|
||||
<p>See version control history for details of individual contributions.</p>
|
||||
|
||||
<p>The above copyright and license notice applies to distributions of
|
||||
CMake in source and binary form. Third-party software packages supplied
|
||||
with CMake under compatible licenses provide their own copyright notices
|
||||
documented in corresponding subdirectories or source files.</p>
|
||||
|
||||
<p>------------------------------------------------------------------------------</p>
|
||||
|
||||
<p>CMake was initially developed by Kitware with the following sponsorship:</p>
|
||||
|
||||
<p>* National Library of Medicine at the National Institutes of Health as part of the Insight Segmentation and Registration Toolkit (ITK).</p>
|
||||
|
||||
<p>* US National Labs (Los Alamos, Livermore, Sandia) ASC Parallel Visualization Initiative.</p>
|
||||
|
||||
<p>* National Alliance for Medical Image Computing (NAMIC) is funded by the National Institutes of Health through the NIH Roadmap for Medical Research, Grant U54 EB005149.</p>
|
||||
|
||||
<p>* Kitware, Inc.</p>
|
||||
</div>
|
||||
|
||||
<div class="section">
|
||||
|
||||
<h2 id="freetype-license">The FreeType Project License</h2>
|
||||
|
|
File diff suppressed because one or more lines are too long
Binary file not shown.
144
dev_sandbox/CMakeLists.txt
Normal file
144
dev_sandbox/CMakeLists.txt
Normal file
|
@ -0,0 +1,144 @@
|
|||
project(dev_sandbox)
|
||||
|
||||
set(SRC
|
||||
main.cpp
|
||||
imgui_renderer.cpp
|
||||
imgui_renderer.hpp
|
||||
)
|
||||
|
||||
if (${PLATFORM_MAC})
|
||||
append(SRC
|
||||
main.mm
|
||||
../iphone/Maps/Classes/MetalContextFactory.h
|
||||
../iphone/Maps/Classes/MetalContextFactory.mm
|
||||
)
|
||||
|
||||
file(GLOB_RECURSE SHADER_SOURCES_FILES ${OMIM_ROOT}/shaders/Metal/*.metal)
|
||||
add_metal_shader_library(shaders_metal
|
||||
${SHADER_SOURCES_FILES}
|
||||
)
|
||||
endif()
|
||||
|
||||
if (${PLATFORM_LINUX})
|
||||
append(SRC
|
||||
main_linux.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
omim_add_executable(${PROJECT_NAME} MACOSX_BUNDLE ${SRC})
|
||||
|
||||
target_link_libraries(${PROJECT_NAME}
|
||||
generator # For borders::LoadBorders
|
||||
qt_common
|
||||
map
|
||||
gflags::gflags
|
||||
glfw
|
||||
imgui
|
||||
)
|
||||
|
||||
# Installing Vulkan SDK is optional, however without it Vulkan dynamic libraries
|
||||
# should be discovered via system paths and validation layers may not be available
|
||||
find_package(Vulkan QUIET)
|
||||
if (Vulkan_FOUND)
|
||||
message(STATUS "Vulkan found")
|
||||
target_link_libraries(${PROJECT_NAME} Vulkan::Vulkan)
|
||||
endif()
|
||||
|
||||
if(PLATFORM_MAC)
|
||||
target_embed_metal_shader_libraries(${PROJECT_NAME} shaders_metal)
|
||||
endif()
|
||||
|
||||
target_compile_definitions(${PROJECT_NAME} PUBLIC GL_SILENCE_DEPRECATION)
|
||||
if (PLATFORM_MAC)
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES XCODE_ATTRIBUTE_CLANG_ENABLE_OBJC_ARC YES)
|
||||
endif()
|
||||
|
||||
if (PLATFORM_LINUX)
|
||||
target_compile_definitions(${PROJECT_NAME} PRIVATE VK_USE_PLATFORM_XLIB_KHR)
|
||||
endif()
|
||||
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${OMIM_ROOT}/3party/glfw/include)
|
||||
target_include_directories(${PROJECT_NAME} PUBLIC ${OMIM_ROOT}/3party/imgui)
|
||||
|
||||
set(BUNDLE_NAME "OMapsDevSandbox")
|
||||
set(BUNDLE_DISPLAY_NAME "Organic Maps: Developer Sandbox")
|
||||
|
||||
set_target_properties(${PROJECT_NAME} PROPERTIES OUTPUT_NAME ${BUNDLE_NAME})
|
||||
|
||||
set(BUNDLE_EXECUTABLE ${BUNDLE_NAME})
|
||||
|
||||
set(BUNDLE_FOLDER ${CMAKE_BINARY_DIR}/${CMAKE_BUILD_TYPE}/${BUNDLE_NAME}.app)
|
||||
set(RESOURCES_FOLDER ${BUNDLE_FOLDER}/Contents/Resources)
|
||||
set(DATA_DIR ${OMIM_ROOT}/data)
|
||||
|
||||
execute_process(
|
||||
COMMAND mkdir -p ${RESOURCES_FOLDER}/shaders_compiler
|
||||
)
|
||||
|
||||
function(copy_resources)
|
||||
foreach(file ${ARGN})
|
||||
execute_process(
|
||||
COMMAND cp -r ${DATA_DIR}/${file} ${RESOURCES_FOLDER}
|
||||
)
|
||||
endforeach()
|
||||
endfunction()
|
||||
|
||||
copy_resources(
|
||||
countries-strings
|
||||
resources-default
|
||||
resources-mdpi_light
|
||||
resources-hdpi_light
|
||||
resources-xhdpi_light
|
||||
resources-xxhdpi_light
|
||||
resources-xxxhdpi_light
|
||||
resources-6plus_light
|
||||
|
||||
categories.txt
|
||||
categories_cuisines.txt
|
||||
classificator.txt
|
||||
colors.txt
|
||||
countries.txt
|
||||
drules_proto_default_light.bin
|
||||
drules_proto_default_dark.bin
|
||||
drules_proto_vehicle_light.bin
|
||||
drules_proto_vehicle_dark.bin
|
||||
editor.config
|
||||
fonts_blacklist.txt
|
||||
fonts_whitelist.txt
|
||||
packed_polygons.bin
|
||||
patterns.txt
|
||||
transit_colors.txt
|
||||
types.txt
|
||||
unicode_blocks.txt
|
||||
World.mwm
|
||||
WorldCoasts.mwm
|
||||
|
||||
00_NotoNaskhArabic-Regular.ttf
|
||||
00_NotoSansBengali-Regular.ttf
|
||||
00_NotoSansHebrew-Regular.ttf
|
||||
00_NotoSansMalayalam-Regular.ttf
|
||||
00_NotoSansThai-Regular.ttf
|
||||
00_NotoSerifDevanagari-Regular.ttf
|
||||
01_dejavusans.ttf
|
||||
02_droidsans-fallback.ttf
|
||||
03_jomolhari-id-a3d.ttf
|
||||
04_padauk.ttf
|
||||
05_khmeros.ttf
|
||||
06_code2000.ttf
|
||||
07_roboto_medium.ttf
|
||||
)
|
||||
|
||||
if (NOT PLATFORM_LINUX)
|
||||
# On Linux, ICU data is loaded from the shared library.
|
||||
copy_resources(icudt75l.dat)
|
||||
endif()
|
||||
|
||||
if (PLATFORM_MAC)
|
||||
execute_process(
|
||||
COMMAND cp -r ${OMIM_ROOT}/tools/shaders_compiler/macos ${RESOURCES_FOLDER}/shaders_compiler
|
||||
)
|
||||
elseif (PLATFORM_LINUX)
|
||||
execute_process(
|
||||
COMMAND cp -r ${OMIM_ROOT}/tools/shaders_compiler/linux ${RESOURCES_FOLDER}/shaders_compiler
|
||||
)
|
||||
endif()
|
257
dev_sandbox/imgui_renderer.cpp
Normal file
257
dev_sandbox/imgui_renderer.cpp
Normal file
|
@ -0,0 +1,257 @@
|
|||
#include "imgui_renderer.hpp"
|
||||
|
||||
#include "base/logging.hpp"
|
||||
#include "base/macros.hpp"
|
||||
|
||||
#include <drape_frontend/render_state_extension.hpp>
|
||||
|
||||
#include <shaders/program_manager.hpp>
|
||||
|
||||
#include <imgui/imgui.h>
|
||||
|
||||
#include <cstring>
|
||||
#include <limits>
|
||||
|
||||
ImguiRenderer::ImguiRenderer()
|
||||
: m_state(df::CreateRenderState(gpu::Program::ImGui, df::DepthLayer::GuiLayer))
|
||||
{
|
||||
m_state.SetDepthTestEnabled(false);
|
||||
m_state.SetBlending(dp::Blending(true));
|
||||
}
|
||||
|
||||
void ImguiRenderer::Render(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::TextureManager> textureManager,
|
||||
ref_ptr<gpu::ProgramManager> programManager)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_bufferMutex);
|
||||
size_t renderDataIndex = (m_updateIndex + 1) % m_uiDataBuffer.size();
|
||||
UiDataBuffer & dataBuffer = m_uiDataBuffer[renderDataIndex];
|
||||
|
||||
auto gpuProgram = programManager->GetProgram(m_state.GetProgram<gpu::Program>());
|
||||
|
||||
bool needUpdate = true;
|
||||
if (!m_mesh || dataBuffer.m_vertices.size() > m_vertexCount || dataBuffer.m_indices.size() > m_indexCount)
|
||||
{
|
||||
while (dataBuffer.m_vertices.size() > m_vertexCount)
|
||||
m_vertexCount *= 2;
|
||||
while (dataBuffer.m_indices.size() > m_indexCount)
|
||||
m_indexCount *= 2;
|
||||
m_indexCount = std::min(m_indexCount, static_cast<uint32_t>(std::numeric_limits<uint16_t>::max()));
|
||||
|
||||
dataBuffer.m_vertices.resize(m_vertexCount);
|
||||
dataBuffer.m_indices.resize(m_indexCount);
|
||||
|
||||
m_mesh = make_unique_dp<dp::MeshObject>(context, dp::MeshObject::DrawPrimitive::Triangles, "imGui");
|
||||
|
||||
m_mesh->SetBuffer(0, std::move(dataBuffer.m_vertices));
|
||||
m_mesh->SetAttribute("a_position", 0, 0 /* offset */, 2);
|
||||
m_mesh->SetAttribute("a_texCoords", 0, 2 * sizeof(float) /* offset */, 2);
|
||||
m_mesh->SetAttribute("a_color", 0, 4 * sizeof(float) /* offset */, 4);
|
||||
m_mesh->SetIndexBuffer(std::move(dataBuffer.m_indices));
|
||||
m_mesh->Build(context, gpuProgram);
|
||||
|
||||
dataBuffer.m_vertices.clear();
|
||||
dataBuffer.m_indices.clear();
|
||||
needUpdate = false;
|
||||
}
|
||||
|
||||
if (!m_texture)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_textureMutex);
|
||||
if (!m_textureData.empty())
|
||||
{
|
||||
m_texture = make_unique_dp<dp::StaticTexture>();
|
||||
m_texture->Create(context,
|
||||
dp::Texture::Params{
|
||||
.m_width = m_textureWidth,
|
||||
.m_height = m_textureHeight,
|
||||
.m_format = dp::TextureFormat::RGBA8,
|
||||
.m_allocator = textureManager->GetTextureAllocator(),
|
||||
},
|
||||
m_textureData.data());
|
||||
m_textureData.clear();
|
||||
m_state.SetColorTexture(make_ref(m_texture));
|
||||
}
|
||||
else
|
||||
{
|
||||
// Can't render without texture.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (dataBuffer.m_drawCalls.empty())
|
||||
return;
|
||||
|
||||
if (needUpdate && !dataBuffer.m_vertices.empty() && !dataBuffer.m_indices.empty())
|
||||
{
|
||||
m_mesh->UpdateBuffer(context, 0, dataBuffer.m_vertices);
|
||||
m_mesh->UpdateIndexBuffer(context, dataBuffer.m_indices);
|
||||
dataBuffer.m_vertices.clear();
|
||||
dataBuffer.m_indices.clear();
|
||||
}
|
||||
|
||||
gpu::ImGuiProgramParams const params{.m_projection = m_projection};
|
||||
context->PushDebugLabel("ImGui Rendering");
|
||||
m_mesh->Render(context, gpuProgram, m_state, programManager->GetParamsSetter(), params,
|
||||
[&, this]()
|
||||
{
|
||||
context->SetCullingEnabled(false);
|
||||
for (auto const & drawCall : dataBuffer.m_drawCalls)
|
||||
{
|
||||
uint32_t y = drawCall.clipRect.y;
|
||||
if (context->GetApiVersion() == dp::ApiVersion::OpenGLES3)
|
||||
y = dataBuffer.m_height - y - drawCall.clipRect.w;
|
||||
context->SetScissor(drawCall.clipRect.x, y, drawCall.clipRect.z, drawCall.clipRect.w);
|
||||
m_mesh->DrawPrimitivesSubsetIndexed(context, drawCall.indexCount, drawCall.startIndex);
|
||||
}
|
||||
context->SetCullingEnabled(true);
|
||||
context->SetScissor(0, 0, dataBuffer.m_width, dataBuffer.m_height);
|
||||
});
|
||||
context->PopDebugLabel();
|
||||
}
|
||||
|
||||
void ImguiRenderer::Update(std::function<void()> const & uiCallback)
|
||||
{
|
||||
CHECK(uiCallback, ());
|
||||
ImGuiIO & io = ImGui::GetIO();
|
||||
if (!io.Fonts->IsBuilt())
|
||||
io.Fonts->Build();
|
||||
if (!m_texture)
|
||||
UpdateTexture();
|
||||
|
||||
ImGui::NewFrame();
|
||||
uiCallback();
|
||||
ImGui::Render();
|
||||
UpdateBuffers();
|
||||
}
|
||||
|
||||
void ImguiRenderer::Reset()
|
||||
{
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_textureMutex);
|
||||
m_texture.reset();
|
||||
}
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_bufferMutex);
|
||||
m_mesh.reset();
|
||||
}
|
||||
}
|
||||
|
||||
void ImguiRenderer::UpdateTexture()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_textureMutex);
|
||||
unsigned char * pixels;
|
||||
int width, height;
|
||||
ImGui::GetIO().Fonts->GetTexDataAsRGBA32(&pixels, &width, &height);
|
||||
|
||||
auto const sizeInBytes = width * height * sizeof(uint32_t);
|
||||
m_textureData.resize(sizeInBytes);
|
||||
memcpy(m_textureData.data(), pixels, sizeInBytes);
|
||||
m_textureWidth = static_cast<uint32_t>(width);
|
||||
m_textureHeight = static_cast<uint32_t>(height);
|
||||
}
|
||||
|
||||
void ImguiRenderer::UpdateBuffers()
|
||||
{
|
||||
UiDataBuffer & dataBuffer = m_uiDataBuffer[m_updateIndex];
|
||||
dataBuffer.m_drawCalls.clear();
|
||||
|
||||
ImDrawData * dd = ImGui::GetDrawData();
|
||||
auto const fbWidth = static_cast<int>(dd->DisplaySize.x * dd->FramebufferScale.x);
|
||||
auto const fbHeight = static_cast<int>(dd->DisplaySize.y * dd->FramebufferScale.y);
|
||||
if (fbWidth <= 0 || fbHeight <= 0 || dd->CmdListsCount == 0 || dd->TotalIdxCount == 0 || dd->TotalVtxCount == 0)
|
||||
return;
|
||||
dataBuffer.m_width = static_cast<uint32_t>(fbWidth);
|
||||
dataBuffer.m_height = static_cast<uint32_t>(fbHeight);
|
||||
|
||||
CHECK(dd->TotalVtxCount <= std::numeric_limits<uint16_t>::max(),
|
||||
("UI is so complex and now requires 32-bit indices. You need to improve dp::MeshObject or simplify UI"));
|
||||
|
||||
CHECK((ImGui::GetIO().BackendFlags & ImGuiBackendFlags_RendererHasVtxOffset) == 0, ());
|
||||
|
||||
dataBuffer.m_vertices.resize(dd->TotalVtxCount);
|
||||
dataBuffer.m_indices.resize(dd->TotalIdxCount);
|
||||
|
||||
int totalDrawCallsCount = 0;
|
||||
for (int i = 0; i < dd->CmdListsCount; ++i)
|
||||
totalDrawCallsCount += dd->CmdLists[i]->CmdBuffer.Size;
|
||||
dataBuffer.m_drawCalls.reserve(totalDrawCallsCount);
|
||||
|
||||
ImVec2 const clipOff = dd->DisplayPos;
|
||||
ImVec2 const clipScale = dd->FramebufferScale;
|
||||
|
||||
uint32_t vertexOffset = 0;
|
||||
uint32_t indexOffset = 0;
|
||||
for (int i = 0; i < dd->CmdListsCount; ++i)
|
||||
{
|
||||
ImDrawList const * cmdList = dd->CmdLists[i];
|
||||
for (int j = 0; j < cmdList->VtxBuffer.Size; ++j)
|
||||
{
|
||||
dp::Color color(cmdList->VtxBuffer.Data[j].col);
|
||||
dataBuffer.m_vertices[j + vertexOffset] = {
|
||||
.position = {cmdList->VtxBuffer.Data[j].pos.x, cmdList->VtxBuffer.Data[j].pos.y},
|
||||
.texCoords = {cmdList->VtxBuffer.Data[j].uv.x, cmdList->VtxBuffer.Data[j].uv.y},
|
||||
.color = {color.GetAlphaF(), color.GetBlueF(), color.GetGreenF(),
|
||||
color.GetRedF()} // Byte order is reversed in imGui
|
||||
};
|
||||
}
|
||||
|
||||
static_assert(sizeof(uint16_t) == sizeof(ImDrawIdx));
|
||||
memcpy(dataBuffer.m_indices.data() + indexOffset, cmdList->IdxBuffer.Data,
|
||||
cmdList->IdxBuffer.Size * sizeof(ImDrawIdx));
|
||||
for (int j = 0; j < cmdList->IdxBuffer.Size; ++j)
|
||||
{
|
||||
uint32_t indexValue = dataBuffer.m_indices[j + indexOffset];
|
||||
indexValue += vertexOffset;
|
||||
CHECK(indexValue <= std::numeric_limits<uint16_t>::max(), ());
|
||||
dataBuffer.m_indices[j + indexOffset] = static_cast<uint16_t>(indexValue);
|
||||
}
|
||||
|
||||
for (int cmdIndex = 0; cmdIndex < cmdList->CmdBuffer.Size; ++cmdIndex)
|
||||
{
|
||||
const ImDrawCmd cmd = cmdList->CmdBuffer[cmdIndex];
|
||||
ImVec2 clipMin((cmd.ClipRect.x - clipOff.x) * clipScale.x, (cmd.ClipRect.y - clipOff.y) * clipScale.y);
|
||||
ImVec2 clipMax((cmd.ClipRect.z - clipOff.x) * clipScale.x, (cmd.ClipRect.w - clipOff.y) * clipScale.y);
|
||||
if (clipMin.x < 0.0f)
|
||||
clipMin.x = 0.0f;
|
||||
if (clipMin.y < 0.0f)
|
||||
clipMin.y = 0.0f;
|
||||
if (clipMax.x > fbWidth)
|
||||
clipMax.x = static_cast<float>(fbWidth);
|
||||
if (clipMax.y > fbHeight)
|
||||
clipMax.y = static_cast<float>(fbHeight);
|
||||
if (clipMax.x <= clipMin.x || clipMax.y <= clipMin.y)
|
||||
continue;
|
||||
|
||||
dataBuffer.m_drawCalls.emplace_back(DrawCall{
|
||||
.indexCount = static_cast<uint32_t>(cmd.ElemCount),
|
||||
.startIndex = static_cast<uint32_t>(indexOffset + cmd.IdxOffset),
|
||||
.clipRect = {static_cast<uint32_t>(clipMin.x), static_cast<uint32_t>(clipMin.y),
|
||||
static_cast<uint32_t>(clipMax.x - clipMin.x), static_cast<uint32_t>(clipMax.y - clipMin.y)}});
|
||||
}
|
||||
|
||||
vertexOffset += static_cast<uint32_t>(cmdList->VtxBuffer.Size);
|
||||
indexOffset += static_cast<uint32_t>(cmdList->IdxBuffer.Size);
|
||||
}
|
||||
CHECK(vertexOffset == dataBuffer.m_vertices.size(), ());
|
||||
CHECK(indexOffset == dataBuffer.m_indices.size(), ());
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_bufferMutex);
|
||||
|
||||
// Projection
|
||||
float const left = dd->DisplayPos.x;
|
||||
float const right = dd->DisplayPos.x + dd->DisplaySize.x;
|
||||
float const top = dd->DisplayPos.y;
|
||||
float const bottom = dd->DisplayPos.y + dd->DisplaySize.y;
|
||||
m_projection[0][0] = 2.0f / (right - left);
|
||||
m_projection[1][1] = 2.0f / (top - bottom);
|
||||
m_projection[2][2] = -1.0f;
|
||||
m_projection[3][3] = 1.0f;
|
||||
m_projection[0][3] = -(right + left) / (right - left);
|
||||
m_projection[1][3] = -(top + bottom) / (top - bottom);
|
||||
|
||||
// Swap buffers
|
||||
m_updateIndex = (m_updateIndex + 1) % m_uiDataBuffer.size();
|
||||
}
|
||||
}
|
72
dev_sandbox/imgui_renderer.hpp
Normal file
72
dev_sandbox/imgui_renderer.hpp
Normal file
|
@ -0,0 +1,72 @@
|
|||
#pragma once
|
||||
|
||||
#include "drape/glsl_types.hpp"
|
||||
#include "drape/graphics_context.hpp"
|
||||
#include "drape/mesh_object.hpp"
|
||||
#include "drape/pointers.hpp"
|
||||
#include "drape/render_state.hpp"
|
||||
#include "drape/static_texture.hpp"
|
||||
#include "drape/texture_manager.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
|
||||
class ImguiRenderer
|
||||
{
|
||||
public:
|
||||
ImguiRenderer();
|
||||
void Render(ref_ptr<dp::GraphicsContext> context,
|
||||
ref_ptr<dp::TextureManager> textureManager,
|
||||
ref_ptr<gpu::ProgramManager> programManager);
|
||||
void Update(std::function<void()> const & uiCallback);
|
||||
void Reset();
|
||||
|
||||
private:
|
||||
void UpdateTexture();
|
||||
void UpdateBuffers();
|
||||
|
||||
struct ImguiVertex
|
||||
{
|
||||
glsl::vec2 position;
|
||||
glsl::vec2 texCoords;
|
||||
glsl::vec4 color;
|
||||
};
|
||||
static_assert(sizeof(ImguiVertex) == 2 * sizeof(glsl::vec4));
|
||||
|
||||
struct DrawCall
|
||||
{
|
||||
uint32_t indexCount = 0;
|
||||
uint32_t startIndex = 0;
|
||||
glsl::uvec4 clipRect{};
|
||||
};
|
||||
|
||||
drape_ptr<dp::MeshObject> m_mesh;
|
||||
uint32_t m_vertexCount = 2000;
|
||||
uint32_t m_indexCount = 3000;
|
||||
|
||||
drape_ptr<dp::StaticTexture> m_texture;
|
||||
std::vector<unsigned char> m_textureData;
|
||||
uint32_t m_textureWidth = 0;
|
||||
uint32_t m_textureHeight = 0;
|
||||
|
||||
dp::RenderState m_state;
|
||||
|
||||
struct UiDataBuffer
|
||||
{
|
||||
std::vector<ImguiVertex> m_vertices;
|
||||
std::vector<uint16_t> m_indices;
|
||||
std::vector<DrawCall> m_drawCalls;
|
||||
uint32_t m_width;
|
||||
uint32_t m_height;
|
||||
};
|
||||
std::array<UiDataBuffer, 2> m_uiDataBuffer;
|
||||
size_t m_updateIndex = 0;
|
||||
|
||||
glsl::mat4 m_projection;
|
||||
|
||||
std::mutex m_bufferMutex;
|
||||
std::mutex m_textureMutex;
|
||||
};
|
672
dev_sandbox/main.cpp
Normal file
672
dev_sandbox/main.cpp
Normal file
|
@ -0,0 +1,672 @@
|
|||
#include "dev_sandbox/imgui_renderer.hpp"
|
||||
|
||||
#include "map/framework.hpp"
|
||||
|
||||
#include "platform/platform.hpp"
|
||||
#include "platform/settings.hpp"
|
||||
|
||||
#include "coding/reader.hpp"
|
||||
|
||||
#include "base/logging.hpp"
|
||||
#include "base/macros.hpp"
|
||||
|
||||
#include "std/target_os.hpp"
|
||||
|
||||
#include <chrono>
|
||||
#include <functional>
|
||||
#include <mutex>
|
||||
#include <optional>
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <vector>
|
||||
|
||||
#include <gflags/gflags.h>
|
||||
|
||||
#if defined(OMIM_OS_WINDOWS)
|
||||
#define GLFW_EXPOSE_NATIVE_WIN32
|
||||
#elif defined(OMIM_OS_LINUX)
|
||||
#define GLFW_EXPOSE_NATIVE_X11
|
||||
#elif defined(OMIM_OS_MAC)
|
||||
#define GLFW_EXPOSE_NATIVE_COCOA
|
||||
#else
|
||||
#error Unsupported plaform
|
||||
#endif
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
#include <GLFW/glfw3native.h>
|
||||
#include <imgui/backends/imgui_impl_glfw.h>
|
||||
#include <imgui/imgui.h>
|
||||
|
||||
DEFINE_string(data_path, "", "Path to data directory.");
|
||||
DEFINE_string(log_abort_level, base::ToString(base::GetDefaultLogAbortLevel()),
|
||||
"Log messages severity that causes termination.");
|
||||
DEFINE_string(resources_path, "", "Path to resources directory.");
|
||||
DEFINE_string(lang, "", "Device language.");
|
||||
|
||||
#if defined(OMIM_OS_MAC) || defined(OMIM_OS_LINUX)
|
||||
drape_ptr<dp::GraphicsContextFactory> CreateContextFactory(GLFWwindow * window, dp::ApiVersion api, m2::PointU size);
|
||||
void PrepareDestroyContextFactory(ref_ptr<dp::GraphicsContextFactory> contextFactory);
|
||||
void OnCreateDrapeEngine(GLFWwindow * window, dp::ApiVersion api, ref_ptr<dp::GraphicsContextFactory> contextFactory);
|
||||
void UpdateContentScale(GLFWwindow * window, float scale);
|
||||
void UpdateSize(ref_ptr<dp::GraphicsContextFactory> contextFactory, int w, int h);
|
||||
#endif
|
||||
|
||||
#if defined(OMIM_OS_LINUX)
|
||||
// Workaround for storage::Status compilation issue:
|
||||
// /usr/include/X11/Xlib.h:83:16: note: expanded from macro 'Status'
|
||||
#undef Status
|
||||
#endif
|
||||
|
||||
namespace
|
||||
{
|
||||
bool ValidateLogAbortLevel(char const * flagname, std::string const & value)
|
||||
{
|
||||
if (auto level = base::FromString(value); !level)
|
||||
{
|
||||
std::cerr << "Invalid value for --" << flagname << ": " << value << ", must be one of: ";
|
||||
auto const & names = base::GetLogLevelNames();
|
||||
for (size_t i = 0; i < names.size(); ++i)
|
||||
{
|
||||
if (i != 0)
|
||||
std::cerr << ", ";
|
||||
std::cerr << names[i];
|
||||
}
|
||||
std::cerr << '\n';
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool const g_logAbortLevelDummy = gflags::RegisterFlagValidator(&FLAGS_log_abort_level, &ValidateLogAbortLevel);
|
||||
|
||||
void errorCallback(int error, char const * description) { LOG(LERROR, ("GLFW (", error, "):", description)); }
|
||||
|
||||
std::function<void(int w, int h)> onResize;
|
||||
std::function<void(double x, double y, int button, int action, int mods)> onMouseButton;
|
||||
std::function<void(double x, double y)> onMouseMove;
|
||||
std::function<void(double x, double y, double xOffset, double yOffset)> onScroll;
|
||||
std::function<void(int key, int scancode, int action, int mods)> onKeyboardButton;
|
||||
std::function<void(float xscale, float yscale)> onContentScale;
|
||||
|
||||
df::Touch GetTouch(double x, double y)
|
||||
{
|
||||
return df::Touch{.m_location = m2::PointF(static_cast<float>(x), static_cast<float>(y)), .m_id = 0};
|
||||
}
|
||||
|
||||
df::Touch GetSymmetricalTouch(Framework & framework, df::Touch const & touch)
|
||||
{
|
||||
m2::PointD const pixelCenter = framework.GetVisiblePixelCenter();
|
||||
m2::PointD const symmetricalLocation = pixelCenter + pixelCenter - m2::PointD(touch.m_location);
|
||||
|
||||
df::Touch result;
|
||||
result.m_id = touch.m_id + 1;
|
||||
result.m_location = symmetricalLocation;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
df::TouchEvent GetTouchEvent(Framework & framework, double x, double y, int mods, df::TouchEvent::ETouchType type)
|
||||
{
|
||||
df::TouchEvent event;
|
||||
event.SetTouchType(type);
|
||||
event.SetFirstTouch(GetTouch(x, y));
|
||||
if (mods & GLFW_MOD_SUPER)
|
||||
event.SetSecondTouch(GetSymmetricalTouch(framework, event.GetFirstTouch()));
|
||||
return event;
|
||||
}
|
||||
|
||||
void FormatMapSize(uint64_t sizeInBytes, std::string & units, size_t & sizeToDownload)
|
||||
{
|
||||
int const mbInBytes = 1024 * 1024;
|
||||
int const kbInBytes = 1024;
|
||||
if (sizeInBytes > mbInBytes)
|
||||
{
|
||||
sizeToDownload = (sizeInBytes + mbInBytes - 1) / mbInBytes;
|
||||
units = "MB";
|
||||
}
|
||||
else if (sizeInBytes > kbInBytes)
|
||||
{
|
||||
sizeToDownload = (sizeInBytes + kbInBytes - 1) / kbInBytes;
|
||||
units = "KB";
|
||||
}
|
||||
else
|
||||
{
|
||||
sizeToDownload = sizeInBytes;
|
||||
units = "B";
|
||||
}
|
||||
}
|
||||
|
||||
std::string_view GetMyPoisitionText(location::EMyPositionMode mode)
|
||||
{
|
||||
switch(mode)
|
||||
{
|
||||
case location::EMyPositionMode::PendingPosition: return "Pending";
|
||||
case location::EMyPositionMode::NotFollowNoPosition: return "No position";
|
||||
case location::EMyPositionMode::NotFollow: return "Not follow";
|
||||
case location::EMyPositionMode::Follow: return "Follow";
|
||||
case location::EMyPositionMode::FollowAndRotate: return "Follow and Rotate";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
dp::ApiVersion GetApiVersion(char const * apiLabel)
|
||||
{
|
||||
std::string_view v(apiLabel);
|
||||
if (v == "Metal") return dp::ApiVersion::Metal;
|
||||
if (v == "Vulkan") return dp::ApiVersion::Vulkan;
|
||||
if (v == "OpenGL") return dp::ApiVersion::OpenGLES3;
|
||||
return dp::ApiVersion::Invalid;
|
||||
}
|
||||
|
||||
#if defined(OMIM_OS_LINUX)
|
||||
class LinuxGuiThread : public base::TaskLoop
|
||||
{
|
||||
public:
|
||||
PushResult Push(Task && task) override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
m_tasks.emplace_back(std::move(task));
|
||||
return {true, base::TaskLoop::kNoId};
|
||||
}
|
||||
|
||||
PushResult Push(Task const & task) override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
m_tasks.emplace_back(task);
|
||||
return {true, base::TaskLoop::kNoId};
|
||||
}
|
||||
|
||||
void ExecuteTasks()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_mutex);
|
||||
for (auto & task : m_tasks)
|
||||
task();
|
||||
m_tasks.clear();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<Task> m_tasks;
|
||||
std::mutex m_mutex;
|
||||
};
|
||||
#endif
|
||||
} // namespace
|
||||
|
||||
int main(int argc, char * argv[])
|
||||
{
|
||||
// Our double parsing code (base/string_utils.hpp) needs dots as a floating point delimiters, not commas.
|
||||
// TODO: Refactor our doubles parsing code to use locale-independent delimiters.
|
||||
// For example, https://github.com/google/double-conversion can be used.
|
||||
// See http://dbaron.org/log/20121222-locale for more details.
|
||||
(void)::setenv("LC_NUMERIC", "C", 1);
|
||||
|
||||
Platform & platform = GetPlatform();
|
||||
|
||||
LOG(LINFO, ("Organic Maps: Developer Sandbox", platform.Version(), "detected CPU cores:", platform.CpuCores()));
|
||||
|
||||
gflags::SetUsageMessage("Developer Sandbox.");
|
||||
gflags::SetVersionString(platform.Version());
|
||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||
|
||||
if (!FLAGS_resources_path.empty())
|
||||
platform.SetResourceDir(FLAGS_resources_path);
|
||||
if (!FLAGS_data_path.empty())
|
||||
platform.SetWritableDirForTests(FLAGS_data_path);
|
||||
|
||||
if (auto const logLevel = base::FromString(FLAGS_log_abort_level); logLevel)
|
||||
base::g_LogAbortLevel = *logLevel;
|
||||
else
|
||||
LOG(LCRITICAL, ("Invalid log level:", FLAGS_log_abort_level));
|
||||
|
||||
#if defined(OMIM_OS_LINUX)
|
||||
auto guiThread = std::make_unique<LinuxGuiThread>();
|
||||
auto guiThreadPtr = guiThread.get();
|
||||
platform.SetGuiThread(std::move(guiThread));
|
||||
#endif
|
||||
|
||||
// Init GLFW.
|
||||
glfwSetErrorCallback(errorCallback);
|
||||
if (!glfwInit())
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
glfwWindowHint(GLFW_CLIENT_API, GLFW_NO_API);
|
||||
#if defined(OMIM_OS_WINDOWS)
|
||||
glfwWindowHint(GLFW_SCALE_TO_MONITOR, GLFW_TRUE);
|
||||
#endif
|
||||
auto monitor = glfwGetPrimaryMonitor();
|
||||
auto mode = glfwGetVideoMode(monitor);
|
||||
GLFWwindow * window =
|
||||
glfwCreateWindow(mode->width, mode->height, "Organic Maps: Developer Sandbox", nullptr, nullptr);
|
||||
int fbWidth = 0, fbHeight = 0;
|
||||
glfwGetFramebufferSize(window, &fbWidth, &fbHeight);
|
||||
float xs = 1.0f, ys = 1.0f;
|
||||
glfwGetWindowContentScale(window, &xs, &ys);
|
||||
float visualScale = std::max(xs, ys);
|
||||
|
||||
IMGUI_CHECKVERSION();
|
||||
ImGui::CreateContext();
|
||||
ImGui::GetIO().ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard;
|
||||
ImGui::StyleColorsClassic();
|
||||
glfwMaximizeWindow(window);
|
||||
|
||||
platform.SetupMeasurementSystem();
|
||||
|
||||
bool outvalue;
|
||||
if (!settings::Get(settings::kDeveloperMode, outvalue))
|
||||
settings::Set(settings::kDeveloperMode, true);
|
||||
|
||||
if (!FLAGS_lang.empty())
|
||||
(void)::setenv("LANGUAGE", FLAGS_lang.c_str(), 1);
|
||||
|
||||
FrameworkParams frameworkParams;
|
||||
Framework framework(frameworkParams);
|
||||
|
||||
ImguiRenderer imguiRenderer;
|
||||
Framework::DrapeCreationParams drapeParams{
|
||||
#if defined(OMIM_OS_MAC)
|
||||
.m_apiVersion = dp::ApiVersion::Metal,
|
||||
#else
|
||||
.m_apiVersion = dp::ApiVersion::Vulkan,
|
||||
#endif
|
||||
.m_visualScale = visualScale,
|
||||
.m_surfaceWidth = fbWidth,
|
||||
.m_surfaceHeight = fbHeight,
|
||||
.m_renderInjectionHandler = [&](ref_ptr<dp::GraphicsContext> context,
|
||||
ref_ptr<dp::TextureManager> textureManager,
|
||||
ref_ptr<gpu::ProgramManager> programManager,
|
||||
bool shutdown)
|
||||
{
|
||||
if (shutdown)
|
||||
imguiRenderer.Reset();
|
||||
else
|
||||
imguiRenderer.Render(context, textureManager, programManager);
|
||||
}};
|
||||
gui::Skin guiSkin(gui::ResolveGuiSkinFile("default"), visualScale);
|
||||
guiSkin.Resize(fbWidth, fbHeight);
|
||||
guiSkin.ForEach([&](gui::EWidget widget, gui::Position const & pos) { drapeParams.m_widgetsInitInfo[widget] = pos; });
|
||||
drapeParams.m_widgetsInitInfo[gui::WIDGET_SCALE_FPS_LABEL] = gui::Position(dp::LeftTop);
|
||||
|
||||
drape_ptr<dp::GraphicsContextFactory> contextFactory;
|
||||
auto CreateDrapeEngine = [&](dp::ApiVersion version)
|
||||
{
|
||||
drapeParams.m_apiVersion = version;
|
||||
drapeParams.m_visualScale = visualScale;
|
||||
drapeParams.m_surfaceWidth = fbWidth;
|
||||
drapeParams.m_surfaceHeight = fbHeight;
|
||||
contextFactory = CreateContextFactory(window, drapeParams.m_apiVersion,
|
||||
m2::PointU(static_cast<uint32_t>(drapeParams.m_surfaceWidth),
|
||||
static_cast<uint32_t>(drapeParams.m_surfaceHeight)));
|
||||
auto params = drapeParams;
|
||||
framework.CreateDrapeEngine(make_ref(contextFactory), std::move(params));
|
||||
OnCreateDrapeEngine(window, version, make_ref(contextFactory));
|
||||
framework.SetRenderingEnabled(nullptr);
|
||||
};
|
||||
CreateDrapeEngine(drapeParams.m_apiVersion);
|
||||
|
||||
auto DestroyDrapeEngine = [&]()
|
||||
{
|
||||
framework.SetRenderingDisabled(true);
|
||||
framework.DestroyDrapeEngine();
|
||||
PrepareDestroyContextFactory(make_ref(contextFactory));
|
||||
contextFactory.reset();
|
||||
};
|
||||
|
||||
// Process resizing.
|
||||
onResize = [&](int w, int h)
|
||||
{
|
||||
fbWidth = w;
|
||||
fbHeight = h;
|
||||
if (fbWidth > 0 && fbHeight > 0)
|
||||
{
|
||||
UpdateSize(make_ref(contextFactory), fbWidth, fbHeight);
|
||||
framework.OnSize(fbWidth, fbHeight);
|
||||
|
||||
guiSkin.Resize(w, h);
|
||||
gui::TWidgetsLayoutInfo layout;
|
||||
guiSkin.ForEach([&layout](gui::EWidget w, gui::Position const & pos) { layout[w] = pos.m_pixelPivot; });
|
||||
framework.SetWidgetLayout(std::move(layout));
|
||||
framework.MakeFrameActive();
|
||||
}
|
||||
};
|
||||
glfwSetFramebufferSizeCallback(window, [](GLFWwindow * wnd, int w, int h) { onResize(w, h); });
|
||||
|
||||
// Process change content scale.
|
||||
onContentScale = [&](float xscale, float yscale)
|
||||
{
|
||||
visualScale = std::max(xscale, yscale);
|
||||
framework.UpdateVisualScale(visualScale);
|
||||
|
||||
int w = 0, h = 0;
|
||||
glfwGetWindowSize(window, &w, &h);
|
||||
#if defined(OMIM_OS_MAC)
|
||||
w *= xscale;
|
||||
h *= yscale;
|
||||
#endif
|
||||
|
||||
if (w != fbWidth || h != fbHeight)
|
||||
{
|
||||
#if defined(OMIM_OS_MAC)
|
||||
UpdateContentScale(window, xscale);
|
||||
#endif
|
||||
fbWidth = w;
|
||||
fbHeight = h;
|
||||
UpdateSize(make_ref(contextFactory), fbWidth, fbHeight);
|
||||
framework.OnSize(fbWidth, fbHeight);
|
||||
}
|
||||
};
|
||||
glfwSetWindowContentScaleCallback(window,
|
||||
[](GLFWwindow *, float xscale, float yscale) { onContentScale(xscale, yscale); });
|
||||
|
||||
// Location handler
|
||||
std::optional<ms::LatLon> lastLatLon;
|
||||
bool bearingEnabled = false;
|
||||
float bearing = 0.0f;
|
||||
auto setUserLocation = [&]()
|
||||
{
|
||||
if (lastLatLon)
|
||||
{
|
||||
framework.OnLocationUpdate(
|
||||
location::GpsInfo{.m_source = location::EUser,
|
||||
.m_timestamp = static_cast<double>(std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::system_clock::now().time_since_epoch())
|
||||
.count()) /
|
||||
1000,
|
||||
.m_latitude = lastLatLon->m_lat,
|
||||
.m_longitude = lastLatLon->m_lon,
|
||||
.m_horizontalAccuracy = 10,
|
||||
.m_bearing = bearingEnabled ? bearing : -1.0f});
|
||||
if (bearingEnabled)
|
||||
{
|
||||
framework.OnCompassUpdate(location::CompassInfo{.m_bearing = base::DegToRad(bearing)});
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Download maps handler
|
||||
std::string downloadButtonLabel;
|
||||
std::string retryButtonLabel;
|
||||
std::string downloadStatusLabel;
|
||||
storage::CountryId lastCountry;
|
||||
auto const onCountryChanged = [&](storage::CountryId const & countryId)
|
||||
{
|
||||
downloadButtonLabel.clear();
|
||||
retryButtonLabel.clear();
|
||||
downloadStatusLabel.clear();
|
||||
lastCountry = countryId;
|
||||
// Called by Framework in World zoom level.
|
||||
if (countryId.empty())
|
||||
return;
|
||||
|
||||
auto const & storage = framework.GetStorage();
|
||||
auto status = storage.CountryStatusEx(countryId);
|
||||
auto const & countryName = countryId;
|
||||
|
||||
if (status == storage::Status::NotDownloaded)
|
||||
{
|
||||
std::string units;
|
||||
size_t sizeToDownload = 0;
|
||||
FormatMapSize(storage.CountrySizeInBytes(countryId).second, units, sizeToDownload);
|
||||
std::stringstream str;
|
||||
str << "Download (" << countryName << ") " << sizeToDownload << units;
|
||||
downloadButtonLabel = str.str();
|
||||
}
|
||||
else if (status == storage::Status::InQueue)
|
||||
{
|
||||
std::stringstream str;
|
||||
str << countryName << " is waiting for downloading";
|
||||
downloadStatusLabel = str.str();
|
||||
}
|
||||
else if (status != storage::Status::Downloading && status != storage::Status::OnDisk &&
|
||||
status != storage::Status::OnDiskOutOfDate)
|
||||
{
|
||||
std::stringstream str;
|
||||
str << "Retry to download " << countryName;
|
||||
retryButtonLabel = str.str();
|
||||
}
|
||||
};
|
||||
framework.SetCurrentCountryChangedListener(onCountryChanged);
|
||||
|
||||
framework.GetStorage().Subscribe(
|
||||
[&](storage::CountryId const & countryId)
|
||||
{
|
||||
// Storage also calls notifications for parents, but we are interested in leafs only.
|
||||
if (framework.GetStorage().IsLeaf(countryId))
|
||||
onCountryChanged(countryId);
|
||||
},
|
||||
[&](storage::CountryId const & countryId, downloader::Progress const & progress)
|
||||
{
|
||||
std::stringstream str;
|
||||
str << "Downloading (" << countryId << ") " << (progress.m_bytesDownloaded * 100 / progress.m_bytesTotal)
|
||||
<< "%";
|
||||
downloadStatusLabel = str.str();
|
||||
framework.MakeFrameActive();
|
||||
});
|
||||
|
||||
// Handle mouse buttons.
|
||||
bool touchActive = false;
|
||||
int touchMods = 0;
|
||||
bool setUpLocationByLeftClick = false;
|
||||
onMouseButton = [&](double x, double y, int button, int action, int mods)
|
||||
{
|
||||
#if defined(OMIM_OS_LINUX)
|
||||
ImGui::GetIO().MousePos = ImVec2(x / visualScale, y / visualScale);
|
||||
#endif
|
||||
if (ImGui::GetIO().WantCaptureMouse)
|
||||
{
|
||||
framework.MakeFrameActive();
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(OMIM_OS_MAC)
|
||||
x *= visualScale;
|
||||
y *= visualScale;
|
||||
#endif
|
||||
lastLatLon = mercator::ToLatLon(framework.PtoG(m2::PointD(x, y)));
|
||||
|
||||
if (setUpLocationByLeftClick)
|
||||
{
|
||||
setUserLocation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (button == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
|
||||
{
|
||||
framework.TouchEvent(GetTouchEvent(framework, x, y, mods, df::TouchEvent::TOUCH_DOWN));
|
||||
touchActive = true;
|
||||
touchMods = mods;
|
||||
}
|
||||
|
||||
if (touchActive && action == GLFW_RELEASE)
|
||||
{
|
||||
framework.TouchEvent(GetTouchEvent(framework, x, y, 0, df::TouchEvent::TOUCH_UP));
|
||||
touchActive = false;
|
||||
touchMods = 0;
|
||||
}
|
||||
};
|
||||
glfwSetMouseButtonCallback(window,
|
||||
[](GLFWwindow * wnd, int button, int action, int mods)
|
||||
{
|
||||
double x, y;
|
||||
glfwGetCursorPos(wnd, &x, &y);
|
||||
onMouseButton(x, y, button, action, mods);
|
||||
});
|
||||
|
||||
// Handle mouse moving.
|
||||
onMouseMove = [&](double x, double y)
|
||||
{
|
||||
#if defined(OMIM_OS_LINUX)
|
||||
ImGui::GetIO().MousePos = ImVec2(x / visualScale, y / visualScale);
|
||||
#endif
|
||||
if (ImGui::GetIO().WantCaptureMouse)
|
||||
framework.MakeFrameActive();
|
||||
|
||||
if (touchActive)
|
||||
{
|
||||
#if defined(OMIM_OS_MAC)
|
||||
x *= visualScale;
|
||||
y *= visualScale;
|
||||
#endif
|
||||
framework.TouchEvent(
|
||||
GetTouchEvent(framework, x, y, touchMods, df::TouchEvent::TOUCH_MOVE));
|
||||
}
|
||||
};
|
||||
glfwSetCursorPosCallback(window, [](GLFWwindow *, double x, double y) { onMouseMove(x, y); });
|
||||
|
||||
// Handle scroll.
|
||||
onScroll = [&](double x, double y, double xOffset, double yOffset)
|
||||
{
|
||||
#if defined(OMIM_OS_LINUX)
|
||||
ImGui::GetIO().MousePos = ImVec2(x / visualScale, y / visualScale);
|
||||
#endif
|
||||
if (ImGui::GetIO().WantCaptureMouse)
|
||||
{
|
||||
framework.MakeFrameActive();
|
||||
return;
|
||||
}
|
||||
|
||||
#if defined(OMIM_OS_MAC)
|
||||
x *= visualScale;
|
||||
y *= visualScale;
|
||||
#endif
|
||||
constexpr double kSensitivity = 0.01;
|
||||
double const factor = yOffset * kSensitivity;
|
||||
framework.Scale(exp(factor), m2::PointD(x, y), false);
|
||||
};
|
||||
glfwSetScrollCallback(window,
|
||||
[](GLFWwindow * wnd, double xoffset, double yoffset)
|
||||
{
|
||||
double x, y;
|
||||
glfwGetCursorPos(wnd, &x, &y);
|
||||
onScroll(x, y, xoffset, yoffset);
|
||||
});
|
||||
|
||||
// Keys.
|
||||
onKeyboardButton = [&](int key, int scancode, int action, int mods) {};
|
||||
glfwSetKeyCallback(window, [](GLFWwindow *, int key, int scancode, int action, int mods)
|
||||
{ onKeyboardButton(key, scancode, action, mods); });
|
||||
|
||||
// imGui UI
|
||||
bool enableDebugRectRendering = false;
|
||||
bool enableAA = false;
|
||||
auto imGuiUI = [&]()
|
||||
{
|
||||
ImGui::SetNextWindowPos(ImVec2(5, 20), ImGuiCond_Appearing);
|
||||
ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
|
||||
|
||||
// Drape controls
|
||||
char const * apiLabels[] = {
|
||||
#if defined(OMIM_OS_MAC)
|
||||
"Metal",
|
||||
"Vulkan",
|
||||
"OpenGL"
|
||||
#elif defined(OMIM_OS_LINUX)
|
||||
"Vulkan",
|
||||
"OpenGL"
|
||||
#endif
|
||||
};
|
||||
static int currentAPI = 0;
|
||||
if (ImGui::Combo("API", ¤tAPI, apiLabels, IM_ARRAYSIZE(apiLabels)))
|
||||
{
|
||||
auto const apiVersion = GetApiVersion(apiLabels[currentAPI]);
|
||||
if (framework.GetDrapeEngine()->GetApiVersion() != apiVersion)
|
||||
{
|
||||
DestroyDrapeEngine();
|
||||
CreateDrapeEngine(apiVersion);
|
||||
}
|
||||
}
|
||||
if (ImGui::Checkbox("Debug rect rendering", &enableDebugRectRendering))
|
||||
framework.EnableDebugRectRendering(enableDebugRectRendering);
|
||||
if (ImGui::Checkbox("Antialiasing", &enableAA))
|
||||
framework.GetDrapeEngine()->SetPosteffectEnabled(df::PostprocessRenderer::Antialiasing, enableAA);
|
||||
ImGui::NewLine();
|
||||
ImGui::Separator();
|
||||
ImGui::NewLine();
|
||||
|
||||
// Map controls
|
||||
if (ImGui::Button("Scale +"))
|
||||
framework.Scale(Framework::SCALE_MAG, true);
|
||||
ImGui::SameLine();
|
||||
if (ImGui::Button("Scale -"))
|
||||
framework.Scale(Framework::SCALE_MIN, true);
|
||||
ImGui::Checkbox("Set up location by left click", &setUpLocationByLeftClick);
|
||||
if (setUpLocationByLeftClick)
|
||||
{
|
||||
if (ImGui::Checkbox("Bearing", &bearingEnabled))
|
||||
setUserLocation();
|
||||
ImGui::SameLine();
|
||||
if (ImGui::SliderFloat(" ", &bearing, 0.0f, 360.0f, "%.1f"))
|
||||
setUserLocation();
|
||||
}
|
||||
ImGui::Text("My positon mode: %s", GetMyPoisitionText(framework.GetMyPositionMode()).data());
|
||||
if (ImGui::Button("Next Position Mode"))
|
||||
framework.SwitchMyPositionNextMode();
|
||||
ImGui::NewLine();
|
||||
ImGui::Separator();
|
||||
ImGui::NewLine();
|
||||
|
||||
// No downloading on Linux at the moment, need to implement http_thread without Qt.
|
||||
#if !defined(OMIM_OS_LINUX)
|
||||
// Download controls
|
||||
if (!downloadButtonLabel.empty())
|
||||
{
|
||||
if (ImGui::Button(downloadButtonLabel.c_str()))
|
||||
framework.GetStorage().DownloadNode(lastCountry);
|
||||
}
|
||||
if (!retryButtonLabel.empty())
|
||||
{
|
||||
if (ImGui::Button(retryButtonLabel.c_str()))
|
||||
framework.GetStorage().RetryDownloadNode(lastCountry);
|
||||
}
|
||||
if (!downloadStatusLabel.empty())
|
||||
ImGui::Text("%s", downloadStatusLabel.c_str());
|
||||
if (!downloadButtonLabel.empty() || !retryButtonLabel.empty() || !downloadStatusLabel.empty())
|
||||
{
|
||||
ImGui::NewLine();
|
||||
ImGui::Separator();
|
||||
ImGui::NewLine();
|
||||
}
|
||||
#endif
|
||||
|
||||
ImGui::End();
|
||||
};
|
||||
|
||||
ImGui_ImplGlfw_InitForOther(window, true);
|
||||
|
||||
// Main loop.
|
||||
while (!glfwWindowShouldClose(window))
|
||||
{
|
||||
glfwPollEvents();
|
||||
|
||||
#if defined(OMIM_OS_LINUX)
|
||||
guiThreadPtr->ExecuteTasks();
|
||||
#endif
|
||||
|
||||
// Render imGui UI
|
||||
ImGui_ImplGlfw_NewFrame();
|
||||
ImGuiIO& io = ImGui::GetIO();
|
||||
#if defined(OMIM_OS_LINUX)
|
||||
// Apply correct visual scale on Linux
|
||||
// In glfw for Linux, window size and framebuffer size are the same,
|
||||
// even if visual scale is not 1.0. It's different from behaviour on Mac.
|
||||
io.DisplaySize = ImVec2(fbWidth / visualScale, fbHeight / visualScale);
|
||||
io.DisplayFramebufferScale = ImVec2(visualScale, visualScale);
|
||||
double mouseX, mouseY;
|
||||
glfwGetCursorPos(window, &mouseX, &mouseY);
|
||||
io.AddMousePosEvent((float)mouseX / visualScale, (float)mouseY / visualScale);
|
||||
#endif
|
||||
io.IniFilename = nullptr;
|
||||
imguiRenderer.Update(imGuiUI);
|
||||
std::this_thread::sleep_for(std::chrono::milliseconds(1000 / 30));
|
||||
}
|
||||
|
||||
framework.EnterBackground();
|
||||
DestroyDrapeEngine();
|
||||
|
||||
ImGui_ImplGlfw_Shutdown();
|
||||
ImGui::DestroyContext();
|
||||
|
||||
glfwDestroyWindow(window);
|
||||
glfwTerminate();
|
||||
return 0;
|
||||
}
|
370
dev_sandbox/main.mm
Normal file
370
dev_sandbox/main.mm
Normal file
|
@ -0,0 +1,370 @@
|
|||
#include "iphone/Maps/Classes/MetalContextFactory.h"
|
||||
|
||||
#include "drape/gl_functions.hpp"
|
||||
#include "drape/oglcontext.hpp"
|
||||
#include "drape/metal/metal_base_context.hpp"
|
||||
#include "drape/vulkan/vulkan_context_factory.hpp"
|
||||
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
|
||||
#if __APPLE__
|
||||
#define GLFW_EXPOSE_NATIVE_COCOA
|
||||
#else
|
||||
#error Unsupported OS
|
||||
#endif
|
||||
#include <GLFW/glfw3native.h>
|
||||
|
||||
#import <AppKit/NSOpenGL.h>
|
||||
#import <Cocoa/Cocoa.h>
|
||||
#import <Metal/Metal.h>
|
||||
#import <QuartzCore/CAMetalLayer.h>
|
||||
|
||||
#include <vulkan/vulkan_macos.h>
|
||||
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
class MacOSVulkanContextFactory : public dp::vulkan::VulkanContextFactory
|
||||
{
|
||||
public:
|
||||
MacOSVulkanContextFactory()
|
||||
: dp::vulkan::VulkanContextFactory(1, 33, false) {}
|
||||
|
||||
void SetSurface(CAMetalLayer *layer)
|
||||
{
|
||||
VkMacOSSurfaceCreateInfoMVK createInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_MACOS_SURFACE_CREATE_INFO_MVK,
|
||||
.flags = 0,
|
||||
.pView = static_cast<const void *>(CFBridgingRetain(layer)),
|
||||
};
|
||||
|
||||
VkResult statusCode;
|
||||
CHECK(vkCreateMacOSSurfaceMVK, ());
|
||||
statusCode = vkCreateMacOSSurfaceMVK(m_vulkanInstance, &createInfo, nullptr,
|
||||
&m_surface);
|
||||
if (statusCode != VK_SUCCESS)
|
||||
{
|
||||
LOG_ERROR_VK_CALL(vkCreateMacOSSurfaceMVK, statusCode);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t const renderingQueueIndex = m_drawContext->GetRenderingQueueFamilyIndex();
|
||||
VkBool32 supportsPresent;
|
||||
statusCode = vkGetPhysicalDeviceSurfaceSupportKHR(m_gpu, renderingQueueIndex, m_surface, &supportsPresent);
|
||||
if (statusCode != VK_SUCCESS)
|
||||
{
|
||||
LOG_ERROR_VK_CALL(vkGetPhysicalDeviceSurfaceSupportKHR, statusCode);
|
||||
return;
|
||||
}
|
||||
CHECK_EQUAL(supportsPresent, VK_TRUE, ());
|
||||
|
||||
CHECK(QuerySurfaceSize(), ());
|
||||
|
||||
if (m_drawContext)
|
||||
m_drawContext->SetSurface(m_surface, m_surfaceFormat, m_surfaceCapabilities);
|
||||
}
|
||||
|
||||
void ResetSurface()
|
||||
{
|
||||
if (m_drawContext)
|
||||
m_drawContext->ResetSurface(false);
|
||||
|
||||
vkDestroySurfaceKHR(m_vulkanInstance, m_surface, nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
class MacGLContext : public dp::OGLContext
|
||||
{
|
||||
public:
|
||||
MacGLContext(MacGLContext * contextToShareWith)
|
||||
: m_viewSet(false)
|
||||
{
|
||||
NSOpenGLPixelFormatAttribute attributes[] = {
|
||||
NSOpenGLPFAAccelerated,
|
||||
NSOpenGLPFAOpenGLProfile,
|
||||
NSOpenGLProfileVersion4_1Core,
|
||||
NSOpenGLPFADoubleBuffer,
|
||||
NSOpenGLPFAColorSize,
|
||||
24,
|
||||
NSOpenGLPFAAlphaSize,
|
||||
8,
|
||||
NSOpenGLPFADepthSize,
|
||||
24,
|
||||
NSOpenGLPFAStencilSize,
|
||||
8,
|
||||
0
|
||||
};
|
||||
m_pixelFormat = [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
|
||||
CHECK(m_pixelFormat, ("Pixel format is not found"));
|
||||
m_context = [[NSOpenGLContext alloc] initWithFormat:m_pixelFormat
|
||||
shareContext:(contextToShareWith ? contextToShareWith->m_context : nil)];
|
||||
int interval = 1;
|
||||
[m_context getValues:&interval forParameter:NSOpenGLContextParameterSwapInterval];
|
||||
}
|
||||
|
||||
~MacGLContext()
|
||||
{
|
||||
@autoreleasepool {
|
||||
[m_context clearDrawable];
|
||||
m_pixelFormat = nil;
|
||||
m_context = nil;
|
||||
}
|
||||
}
|
||||
|
||||
bool BeginRendering() override { return m_viewSet; }
|
||||
|
||||
void Present() override
|
||||
{
|
||||
if (m_viewSet)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_updateSizeMutex);
|
||||
[m_context flushBuffer];
|
||||
}
|
||||
}
|
||||
|
||||
void MakeCurrent() override
|
||||
{
|
||||
[m_context makeCurrentContext];
|
||||
}
|
||||
|
||||
void DoneCurrent() override
|
||||
{
|
||||
[NSOpenGLContext clearCurrentContext];
|
||||
}
|
||||
|
||||
void SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) override
|
||||
{
|
||||
if (framebuffer)
|
||||
framebuffer->Bind();
|
||||
else
|
||||
GLFunctions::glBindFramebuffer(0);
|
||||
}
|
||||
|
||||
void SetView(NSView* view)
|
||||
{
|
||||
[m_context setView: view];
|
||||
[m_context update];
|
||||
m_viewSet = true;
|
||||
}
|
||||
|
||||
void UpdateSize(int w, int h)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_updateSizeMutex);
|
||||
[m_context update];
|
||||
}
|
||||
|
||||
private:
|
||||
NSOpenGLPixelFormat * m_pixelFormat = nil;
|
||||
NSOpenGLContext* m_context = nil;
|
||||
std::atomic<bool> m_viewSet;
|
||||
|
||||
std::mutex m_updateSizeMutex;
|
||||
};
|
||||
|
||||
class MacGLContextFactory: public dp::GraphicsContextFactory
|
||||
{
|
||||
public:
|
||||
dp::GraphicsContext * GetDrawContext() override
|
||||
{
|
||||
bool needNotify = false;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_contextAccess);
|
||||
if (m_drawContext == nullptr)
|
||||
{
|
||||
m_drawContext = std::make_unique<MacGLContext>(m_uploadContext.get());
|
||||
needNotify = true;
|
||||
}
|
||||
}
|
||||
if (needNotify)
|
||||
NotifyView();
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_contextAccess);
|
||||
return m_drawContext.get();
|
||||
}
|
||||
|
||||
dp::GraphicsContext * GetResourcesUploadContext() override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_contextAccess);
|
||||
if (m_uploadContext == nullptr)
|
||||
m_uploadContext = std::make_unique<MacGLContext>(m_drawContext.get());
|
||||
return m_uploadContext.get();
|
||||
}
|
||||
|
||||
void WaitForInitialization(dp::GraphicsContext *) override
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_initializationMutex);
|
||||
if (m_isInitialized)
|
||||
return;
|
||||
|
||||
m_initializationCounter++;
|
||||
if (m_initializationCounter >= kGLThreadsCount)
|
||||
{
|
||||
m_isInitialized = true;
|
||||
m_initializationCondition.notify_all();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_initializationCondition.wait(lock, [this] { return m_isInitialized; });
|
||||
}
|
||||
}
|
||||
|
||||
bool IsDrawContextCreated() const override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_contextAccess);
|
||||
return m_drawContext != nullptr;
|
||||
}
|
||||
|
||||
bool IsUploadContextCreated() const override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_contextAccess);
|
||||
return m_uploadContext != nullptr;
|
||||
}
|
||||
|
||||
void SetView(NSView* view)
|
||||
{
|
||||
bool needWait;
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_contextAccess);
|
||||
needWait = (m_drawContext == nullptr);
|
||||
}
|
||||
if (needWait)
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_viewSetMutex);
|
||||
m_viewSetCondition.wait(lock, [this] { return m_viewSet; });
|
||||
}
|
||||
|
||||
std::lock_guard<std::mutex> lock(m_contextAccess);
|
||||
CHECK(m_drawContext, ());
|
||||
m_drawContext->SetView(view);
|
||||
}
|
||||
|
||||
void UpdateSize(int w, int h)
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_contextAccess);
|
||||
if (m_drawContext)
|
||||
m_drawContext->UpdateSize(w, h);
|
||||
}
|
||||
|
||||
private:
|
||||
void NotifyView()
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_viewSetMutex);
|
||||
m_viewSet = true;
|
||||
m_viewSetCondition.notify_all();
|
||||
}
|
||||
|
||||
static size_t constexpr kGLThreadsCount = 2;
|
||||
|
||||
std::unique_ptr<MacGLContext> m_drawContext;
|
||||
std::unique_ptr<MacGLContext> m_uploadContext;
|
||||
|
||||
mutable std::mutex m_contextAccess;
|
||||
|
||||
bool m_isInitialized = false;
|
||||
size_t m_initializationCounter = 0;
|
||||
std::condition_variable m_initializationCondition;
|
||||
std::mutex m_initializationMutex;
|
||||
|
||||
bool m_viewSet = false;
|
||||
std::condition_variable m_viewSetCondition;
|
||||
std::mutex m_viewSetMutex;
|
||||
};
|
||||
|
||||
drape_ptr<dp::GraphicsContextFactory> CreateContextFactory(GLFWwindow *window, dp::ApiVersion api, m2::PointU size)
|
||||
{
|
||||
if (api == dp::ApiVersion::Metal)
|
||||
{
|
||||
CAMetalLayer *layer = [CAMetalLayer layer];
|
||||
layer.device = MTLCreateSystemDefaultDevice();
|
||||
layer.opaque = YES;
|
||||
layer.displaySyncEnabled = YES;
|
||||
|
||||
NSWindow *nswindow = glfwGetCocoaWindow(window);
|
||||
NSScreen *screen = [NSScreen mainScreen];
|
||||
CGFloat factor = [screen backingScaleFactor];
|
||||
layer.contentsScale = factor;
|
||||
nswindow.contentView.layer = layer;
|
||||
nswindow.contentView.wantsLayer = YES;
|
||||
|
||||
return make_unique_dp<MetalContextFactory>(layer, size);
|
||||
}
|
||||
|
||||
if (api == dp::ApiVersion::Vulkan)
|
||||
{
|
||||
CAMetalLayer *layer = [CAMetalLayer layer];
|
||||
layer.device = MTLCreateSystemDefaultDevice();
|
||||
layer.opaque = YES;
|
||||
layer.displaySyncEnabled = YES;
|
||||
|
||||
NSWindow *nswindow = glfwGetCocoaWindow(window);
|
||||
NSScreen *screen = [NSScreen mainScreen];
|
||||
CGFloat factor = [screen backingScaleFactor];
|
||||
layer.contentsScale = factor;
|
||||
nswindow.contentView.layer = layer;
|
||||
nswindow.contentView.wantsLayer = YES;
|
||||
|
||||
auto contextFactory = make_unique_dp<MacOSVulkanContextFactory>();
|
||||
contextFactory->SetSurface(layer);
|
||||
return contextFactory;
|
||||
}
|
||||
|
||||
if (api == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
NSWindow *nswindow = glfwGetCocoaWindow(window);
|
||||
[nswindow.contentView setWantsBestResolutionOpenGLSurface:YES];
|
||||
return make_unique_dp<MacGLContextFactory>();
|
||||
}
|
||||
|
||||
ASSERT(false, ("API is not available yet"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void OnCreateDrapeEngine(GLFWwindow *window, dp::ApiVersion api,
|
||||
ref_ptr<dp::GraphicsContextFactory> contextFactory)
|
||||
{
|
||||
if (api == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
NSWindow *nswindow = glfwGetCocoaWindow(window);
|
||||
ref_ptr<MacGLContextFactory> macosContextFactory = contextFactory;
|
||||
macosContextFactory->SetView(nswindow.contentView);
|
||||
}
|
||||
}
|
||||
|
||||
void PrepareDestroyContextFactory(ref_ptr<dp::GraphicsContextFactory> contextFactory)
|
||||
{
|
||||
auto const api = contextFactory->GetDrawContext()->GetApiVersion();
|
||||
if (api == dp::ApiVersion::Metal || api == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else if (api == dp::ApiVersion::Vulkan)
|
||||
{
|
||||
ref_ptr<MacOSVulkanContextFactory> macosContextFactory = contextFactory;
|
||||
macosContextFactory->ResetSurface();
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(false, ("API is not available yet"));
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateContentScale(GLFWwindow *window, float scale)
|
||||
{
|
||||
NSWindow *nswindow = glfwGetCocoaWindow(window);
|
||||
if (nswindow.contentView.layer)
|
||||
nswindow.contentView.layer.contentsScale = scale;
|
||||
}
|
||||
|
||||
void UpdateSize(ref_ptr<dp::GraphicsContextFactory> contextFactory, int w, int h)
|
||||
{
|
||||
if (!contextFactory || !contextFactory->GetDrawContext())
|
||||
return;
|
||||
|
||||
auto const api = contextFactory->GetDrawContext()->GetApiVersion();
|
||||
if (api == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
ref_ptr<MacGLContextFactory> macosContextFactory = contextFactory;
|
||||
macosContextFactory->UpdateSize(w, h);
|
||||
}
|
||||
}
|
411
dev_sandbox/main_linux.cpp
Normal file
411
dev_sandbox/main_linux.cpp
Normal file
|
@ -0,0 +1,411 @@
|
|||
#include "std/target_os.hpp"
|
||||
#if !defined(OMIM_OS_LINUX)
|
||||
#error Unsupported OS
|
||||
#endif
|
||||
|
||||
#define GLFW_INCLUDE_NONE
|
||||
#include <GLFW/glfw3.h>
|
||||
#define GLFW_EXPOSE_NATIVE_X11
|
||||
#include <GLFW/glfw3native.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <X11/X.h>
|
||||
|
||||
#include <vulkan_wrapper.h>
|
||||
#include <vulkan/vulkan_xlib.h>
|
||||
// Workaround for TestFunction::Always compilation issue:
|
||||
// /usr/include/X11/X.h:441:33: note: expanded from macro 'Always'
|
||||
#undef Always
|
||||
// Workaround for storage::Status compilation issue:
|
||||
// /usr/include/X11/Xlib.h:83:16: note: expanded from macro 'Status'
|
||||
#undef Status
|
||||
|
||||
#include "drape/vulkan/vulkan_context_factory.hpp"
|
||||
|
||||
#include "drape/gl_functions.hpp"
|
||||
#include "drape/gl_includes.hpp"
|
||||
#include "drape/oglcontext.hpp"
|
||||
|
||||
#include <array>
|
||||
#include <atomic>
|
||||
#include <memory>
|
||||
|
||||
class LinuxVulkanContextFactory : public dp::vulkan::VulkanContextFactory
|
||||
{
|
||||
public:
|
||||
LinuxVulkanContextFactory() : dp::vulkan::VulkanContextFactory(1, 33, false) {}
|
||||
|
||||
void SetSurface(Display * display, Window window)
|
||||
{
|
||||
VkXlibSurfaceCreateInfoKHR const createInfo = {
|
||||
.sType = VK_STRUCTURE_TYPE_XLIB_SURFACE_CREATE_INFO_KHR,
|
||||
.pNext = nullptr,
|
||||
.flags = 0,
|
||||
.dpy = display,
|
||||
.window = window,
|
||||
};
|
||||
|
||||
VkResult statusCode;
|
||||
CHECK(vkCreateXlibSurfaceKHR, ());
|
||||
statusCode = vkCreateXlibSurfaceKHR(m_vulkanInstance, &createInfo, nullptr, &m_surface);
|
||||
if (statusCode != VK_SUCCESS)
|
||||
{
|
||||
LOG_ERROR_VK_CALL(vkCreateXlibSurfaceKHR, statusCode);
|
||||
return;
|
||||
}
|
||||
|
||||
uint32_t const renderingQueueIndex = m_drawContext->GetRenderingQueueFamilyIndex();
|
||||
VkBool32 supportsPresent;
|
||||
statusCode = vkGetPhysicalDeviceSurfaceSupportKHR(m_gpu, renderingQueueIndex, m_surface, &supportsPresent);
|
||||
if (statusCode != VK_SUCCESS)
|
||||
{
|
||||
LOG_ERROR_VK_CALL(vkGetPhysicalDeviceSurfaceSupportKHR, statusCode);
|
||||
return;
|
||||
}
|
||||
CHECK_EQUAL(supportsPresent, VK_TRUE, ());
|
||||
|
||||
CHECK(QuerySurfaceSize(), ());
|
||||
|
||||
if (m_drawContext)
|
||||
m_drawContext->SetSurface(m_surface, m_surfaceFormat, m_surfaceCapabilities);
|
||||
}
|
||||
|
||||
void ResetSurface()
|
||||
{
|
||||
if (m_drawContext)
|
||||
m_drawContext->ResetSurface(false);
|
||||
|
||||
vkDestroySurfaceKHR(m_vulkanInstance, m_surface, nullptr);
|
||||
}
|
||||
};
|
||||
|
||||
// Based on: https://github.com/glfw/glfw/blob/master/src/glx_context.c
|
||||
#define GLX_CONTEXT_CORE_PROFILE_BIT_ARB 0x00000001
|
||||
#define GLX_CONTEXT_PROFILE_MASK_ARB 0x9126
|
||||
#define GLX_CONTEXT_MAJOR_VERSION_ARB 0x2091
|
||||
#define GLX_CONTEXT_MINOR_VERSION_ARB 0x2092
|
||||
#define GLX_PBUFFER_HEIGHT 0x8040
|
||||
#define GLX_PBUFFER_WIDTH 0x8041
|
||||
#define GLX_DOUBLEBUFFER 5
|
||||
#define GLX_DRAWABLE_TYPE 0x8010
|
||||
#define GLX_RENDER_TYPE 0x8011
|
||||
#define GLX_WINDOW_BIT 0x00000001
|
||||
#define GLX_PBUFFER_BIT 0x00000004
|
||||
#define GLX_RGBA_BIT 0x00000001
|
||||
#define GLX_RED_SIZE 8
|
||||
#define GLX_GREEN_SIZE 9
|
||||
#define GLX_BLUE_SIZE 10
|
||||
#define GLX_ALPHA_SIZE 11
|
||||
#define GLX_DEPTH_SIZE 12
|
||||
#define GLX_STENCIL_SIZE 13
|
||||
|
||||
typedef XID GLXDrawable;
|
||||
typedef struct __GLXcontext * GLXContext;
|
||||
typedef XID GLXPbuffer;
|
||||
typedef struct __GLXFBConfig * GLXFBConfig;
|
||||
typedef void (*__GLXextproc)(void);
|
||||
|
||||
typedef __GLXextproc (*PFNGLXGETPROCADDRESSPROC)(const GLubyte * procName);
|
||||
|
||||
typedef int (*PFNXFREE)(void *);
|
||||
typedef GLXFBConfig * (*PFNGLXCHOOSEFBCONFIGPROC)(Display *, int, const int *, int *);
|
||||
typedef GLXContext (*PFNGLXCREATECONTEXTATTRIBSARB)(Display *, GLXFBConfig, GLXContext, Bool, const int *);
|
||||
typedef void (*PFNGLXDESTROYCONTEXT)(Display *, GLXContext);
|
||||
typedef GLXPbuffer (*PFNGLXCREATEPBUFFERPROC)(Display *, GLXFBConfig, const int *);
|
||||
typedef void (*PFNGLXDESTROYPBUFFER)(Display *, GLXPbuffer);
|
||||
typedef Bool (*PFNGLXMAKECURRENTPROC)(Display *, GLXDrawable, GLXContext);
|
||||
typedef void (*PFNGLXSWAPBUFFERSPROC)(Display *, GLXDrawable);
|
||||
|
||||
struct GLXFunctions
|
||||
{
|
||||
GLXFunctions()
|
||||
{
|
||||
std::array<char const *, 3> libs = {
|
||||
"libGLX.so.0",
|
||||
"libGL.so.1",
|
||||
"libGL.so",
|
||||
};
|
||||
|
||||
for (char const * lib : libs)
|
||||
{
|
||||
m_module = dlopen(lib, RTLD_LAZY | RTLD_LOCAL);
|
||||
if (m_module)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
CHECK(m_module != nullptr, ("Failed to initialize GLX"));
|
||||
|
||||
XFree = loadFunction<PFNXFREE>("XFree");
|
||||
|
||||
glXGetProcAddress = loadFunction<PFNGLXGETPROCADDRESSPROC>("glXGetProcAddress");
|
||||
glXGetProcAddressARB = loadFunction<PFNGLXGETPROCADDRESSPROC>("glXGetProcAddressARB");
|
||||
|
||||
glXChooseFBConfig = loadGlxFunction<PFNGLXCHOOSEFBCONFIGPROC>("glXChooseFBConfig");
|
||||
glXCreateContextAttribsARB = loadGlxFunction<PFNGLXCREATECONTEXTATTRIBSARB>("glXCreateContextAttribsARB");
|
||||
|
||||
glXDestroyContext = loadGlxFunction<PFNGLXDESTROYCONTEXT>("glXDestroyContext");
|
||||
glXCreatePbuffer = loadGlxFunction<PFNGLXCREATEPBUFFERPROC>("glXCreatePbuffer");
|
||||
glXDestroyPbuffer = loadGlxFunction<PFNGLXDESTROYPBUFFER>("glXDestroyPbuffer");
|
||||
glXMakeCurrent = loadGlxFunction<PFNGLXMAKECURRENTPROC>("glXMakeCurrent");
|
||||
glXSwapBuffers = loadGlxFunction<PFNGLXSWAPBUFFERSPROC>("glXSwapBuffers");
|
||||
}
|
||||
|
||||
~GLXFunctions()
|
||||
{
|
||||
if (m_module)
|
||||
{
|
||||
dlclose(m_module);
|
||||
}
|
||||
}
|
||||
|
||||
PFNXFREE XFree = nullptr;
|
||||
|
||||
PFNGLXGETPROCADDRESSPROC glXGetProcAddress = nullptr;
|
||||
PFNGLXGETPROCADDRESSPROC glXGetProcAddressARB = nullptr;
|
||||
|
||||
PFNGLXCHOOSEFBCONFIGPROC glXChooseFBConfig = nullptr;
|
||||
PFNGLXCREATECONTEXTATTRIBSARB glXCreateContextAttribsARB = nullptr;
|
||||
PFNGLXDESTROYCONTEXT glXDestroyContext = nullptr;
|
||||
PFNGLXCREATEPBUFFERPROC glXCreatePbuffer = nullptr;
|
||||
PFNGLXDESTROYPBUFFER glXDestroyPbuffer = nullptr;
|
||||
PFNGLXMAKECURRENTPROC glXMakeCurrent = nullptr;
|
||||
PFNGLXSWAPBUFFERSPROC glXSwapBuffers = nullptr;
|
||||
|
||||
private:
|
||||
template <typename T>
|
||||
T loadFunction(char const * func)
|
||||
{
|
||||
auto f = reinterpret_cast<T>(dlsym(m_module, func));
|
||||
ASSERT(f, ("Failed to initialize GLX:", func, "is not found"));
|
||||
return f;
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
T loadGlxFunction(char const * func)
|
||||
{
|
||||
if (auto f = reinterpret_cast<T>(glXGetProcAddress(reinterpret_cast<GLubyte const *>(func))))
|
||||
return f;
|
||||
|
||||
if (auto f = reinterpret_cast<T>(glXGetProcAddressARB(reinterpret_cast<GLubyte const *>(func))))
|
||||
return f;
|
||||
|
||||
return loadFunction<T>(func);
|
||||
}
|
||||
|
||||
void * m_module = nullptr;
|
||||
};
|
||||
|
||||
class LinuxGLContext : public dp::OGLContext
|
||||
{
|
||||
public:
|
||||
LinuxGLContext(GLXFunctions const & glx, Display * display, Window window, LinuxGLContext * contextToShareWith,
|
||||
bool usePixelBuffer)
|
||||
: m_glx(glx), m_display(display), m_window(window)
|
||||
{
|
||||
static int visualAttribs[] = {
|
||||
GLX_DOUBLEBUFFER, True,
|
||||
GLX_RENDER_TYPE, GLX_RGBA_BIT,
|
||||
GLX_DRAWABLE_TYPE, (usePixelBuffer ? GLX_PBUFFER_BIT : GLX_WINDOW_BIT),
|
||||
GLX_RED_SIZE, 8,
|
||||
GLX_GREEN_SIZE, 8,
|
||||
GLX_BLUE_SIZE, 8,
|
||||
GLX_ALPHA_SIZE, 8,
|
||||
GLX_DEPTH_SIZE, 24,
|
||||
GLX_STENCIL_SIZE, 8,
|
||||
None
|
||||
};
|
||||
int contextAttribs[] = {
|
||||
GLX_CONTEXT_PROFILE_MASK_ARB, GLX_CONTEXT_CORE_PROFILE_BIT_ARB,
|
||||
GLX_CONTEXT_MAJOR_VERSION_ARB, 4,
|
||||
GLX_CONTEXT_MINOR_VERSION_ARB, 1,
|
||||
None};
|
||||
int fbcount = 0;
|
||||
if (GLXFBConfig * config = m_glx.glXChooseFBConfig(display, DefaultScreen(display), visualAttribs, &fbcount))
|
||||
{
|
||||
m_context =
|
||||
m_glx.glXCreateContextAttribsARB(display, config[0], contextToShareWith ? contextToShareWith->m_context : 0, True, contextAttribs);
|
||||
CHECK(m_context != nullptr, ("Failed to create GLX context"));
|
||||
|
||||
if (usePixelBuffer)
|
||||
{
|
||||
int pbufferAttribs[] = {GLX_PBUFFER_WIDTH, 1, GLX_PBUFFER_HEIGHT, 1, None};
|
||||
|
||||
m_pixelBufferHandle = m_glx.glXCreatePbuffer(display, config[0], pbufferAttribs);
|
||||
CHECK(m_pixelBufferHandle != 0, ("Failed to create GLX pbuffer"));
|
||||
}
|
||||
|
||||
m_glx.XFree(config);
|
||||
}
|
||||
}
|
||||
|
||||
~LinuxGLContext() override
|
||||
{
|
||||
if (m_pixelBufferHandle)
|
||||
{
|
||||
m_glx.glXDestroyPbuffer(m_display, m_pixelBufferHandle);
|
||||
m_pixelBufferHandle = 0;
|
||||
}
|
||||
if (m_context)
|
||||
{
|
||||
m_glx.glXDestroyContext(m_display, m_context);
|
||||
m_context = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void Present() override
|
||||
{
|
||||
if (!m_pixelBufferHandle)
|
||||
m_glx.glXSwapBuffers(m_display, m_window);
|
||||
}
|
||||
|
||||
void MakeCurrent() override
|
||||
{
|
||||
if (!m_glx.glXMakeCurrent(m_display, m_pixelBufferHandle ? m_pixelBufferHandle : m_window, m_context))
|
||||
LOG(LERROR, ("MakeCurrent(): glXMakeCurrent failed"));
|
||||
}
|
||||
|
||||
void DoneCurrent() override
|
||||
{
|
||||
if (!m_glx.glXMakeCurrent(m_display, None, nullptr))
|
||||
LOG(LERROR, ("DoneCurrent(): glXMakeCurrent failed"));
|
||||
}
|
||||
|
||||
void SetFramebuffer(ref_ptr<dp::BaseFramebuffer> framebuffer) override
|
||||
{
|
||||
if (framebuffer)
|
||||
framebuffer->Bind();
|
||||
else
|
||||
GLFunctions::glBindFramebuffer(0);
|
||||
}
|
||||
|
||||
private:
|
||||
GLXFunctions const & m_glx;
|
||||
|
||||
Display * m_display = nullptr;
|
||||
Window m_window = 0;
|
||||
GLXDrawable m_pixelBufferHandle = 0;
|
||||
GLXContext m_context = nullptr;
|
||||
};
|
||||
|
||||
class LinuxContextFactory : public dp::GraphicsContextFactory
|
||||
{
|
||||
public:
|
||||
LinuxContextFactory(Display * display, Window window) : m_display(display), m_window(window) {}
|
||||
|
||||
dp::GraphicsContext * GetDrawContext() override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_contextAccess);
|
||||
if (m_drawContext == nullptr)
|
||||
m_drawContext = std::make_unique<LinuxGLContext>(m_glx, m_display, m_window, m_uploadContext.get(), false);
|
||||
return m_drawContext.get();
|
||||
}
|
||||
|
||||
dp::GraphicsContext * GetResourcesUploadContext() override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_contextAccess);
|
||||
if (m_uploadContext == nullptr)
|
||||
m_uploadContext = std::make_unique<LinuxGLContext>(m_glx, m_display, 0, m_drawContext.get(), true);
|
||||
return m_uploadContext.get();
|
||||
}
|
||||
|
||||
void WaitForInitialization(dp::GraphicsContext *) override
|
||||
{
|
||||
std::unique_lock<std::mutex> lock(m_initializationMutex);
|
||||
if (m_isInitialized)
|
||||
return;
|
||||
|
||||
m_initializationCounter++;
|
||||
if (m_initializationCounter >= kGLThreadsCount)
|
||||
{
|
||||
m_isInitialized = true;
|
||||
m_initializationCondition.notify_all();
|
||||
}
|
||||
else
|
||||
{
|
||||
m_initializationCondition.wait(lock, [this] { return m_isInitialized; });
|
||||
}
|
||||
}
|
||||
|
||||
bool IsDrawContextCreated() const override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_contextAccess);
|
||||
return m_drawContext != nullptr;
|
||||
}
|
||||
|
||||
bool IsUploadContextCreated() const override
|
||||
{
|
||||
std::lock_guard<std::mutex> lock(m_contextAccess);
|
||||
return m_uploadContext != nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
static size_t constexpr kGLThreadsCount = 2;
|
||||
|
||||
GLXFunctions m_glx;
|
||||
|
||||
Display * m_display = nullptr;
|
||||
Window m_window = 0;
|
||||
|
||||
std::unique_ptr<LinuxGLContext> m_drawContext;
|
||||
std::unique_ptr<LinuxGLContext> m_uploadContext;
|
||||
|
||||
mutable std::mutex m_contextAccess;
|
||||
|
||||
bool m_isInitialized = false;
|
||||
size_t m_initializationCounter = 0;
|
||||
std::condition_variable m_initializationCondition;
|
||||
std::mutex m_initializationMutex;
|
||||
};
|
||||
|
||||
drape_ptr<dp::GraphicsContextFactory> CreateContextFactory(GLFWwindow * window, dp::ApiVersion api, m2::PointU size)
|
||||
{
|
||||
if (api == dp::ApiVersion::Vulkan)
|
||||
{
|
||||
auto contextFactory = make_unique_dp<LinuxVulkanContextFactory>();
|
||||
contextFactory->SetSurface(glfwGetX11Display(), glfwGetX11Window(window));
|
||||
return contextFactory;
|
||||
}
|
||||
|
||||
if (api == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
return make_unique_dp<LinuxContextFactory>(glfwGetX11Display(), glfwGetX11Window(window));
|
||||
}
|
||||
|
||||
ASSERT(false, ("API is not available yet"));
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void OnCreateDrapeEngine(GLFWwindow * window, dp::ApiVersion api, ref_ptr<dp::GraphicsContextFactory> contextFactory)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void PrepareDestroyContextFactory(ref_ptr<dp::GraphicsContextFactory> contextFactory)
|
||||
{
|
||||
auto const api = contextFactory->GetDrawContext()->GetApiVersion();
|
||||
if (api == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
else if (api == dp::ApiVersion::Vulkan)
|
||||
{
|
||||
ref_ptr<LinuxVulkanContextFactory> linuxContextFactory = contextFactory;
|
||||
linuxContextFactory->ResetSurface();
|
||||
}
|
||||
else
|
||||
{
|
||||
ASSERT(false, ("API is not available yet"));
|
||||
}
|
||||
}
|
||||
|
||||
void UpdateContentScale(GLFWwindow * window, float scale)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
void UpdateSize(ref_ptr<dp::GraphicsContextFactory> contextFactory, int w, int h)
|
||||
{
|
||||
// Do nothing
|
||||
}
|
|
@ -115,6 +115,10 @@ sudo apt update && sudo apt install -y \
|
|||
libqt6positioning6-plugins \
|
||||
libqt6positioning6 \
|
||||
libsqlite3-dev \
|
||||
libxrandr-dev \
|
||||
libxinerama-dev \
|
||||
libxcursor-dev \
|
||||
libxi-dev \
|
||||
zlib1g-dev
|
||||
```
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ void DataBuffer::MoveToGPU(ref_ptr<GraphicsContext> context, GPUBuffer::Target t
|
|||
uint32_t const currentSize = m_impl->GetCurrentSize();
|
||||
|
||||
auto const apiVersion = context->GetApiVersion();
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
if (currentSize != 0)
|
||||
{
|
||||
|
|
|
@ -26,7 +26,6 @@ namespace dp
|
|||
enum class ApiVersion
|
||||
{
|
||||
Invalid = -1,
|
||||
OpenGLES2 = 0,
|
||||
OpenGLES3,
|
||||
Metal,
|
||||
Vulkan
|
||||
|
@ -101,7 +100,6 @@ inline std::string DebugPrint(dp::ApiVersion apiVersion)
|
|||
switch (apiVersion)
|
||||
{
|
||||
case dp::ApiVersion::Invalid: return "Invalid";
|
||||
case dp::ApiVersion::OpenGLES2: return "OpenGLES2";
|
||||
case dp::ApiVersion::OpenGLES3: return "OpenGLES3";
|
||||
case dp::ApiVersion::Metal: return "Metal";
|
||||
case dp::ApiVersion::Vulkan: return "Vulkan";
|
||||
|
@ -121,9 +119,6 @@ inline dp::ApiVersion ApiVersionFromString(std::string const & str)
|
|||
return dp::ApiVersion::Vulkan;
|
||||
#endif
|
||||
|
||||
if (str == "OpenGLES2")
|
||||
return dp::ApiVersion::OpenGLES2;
|
||||
|
||||
if (str == "OpenGLES3")
|
||||
return dp::ApiVersion::OpenGLES3;
|
||||
|
||||
|
|
|
@ -105,7 +105,7 @@ UNIT_TEST(UploadingGlyphs)
|
|||
TestingGraphicsContext context;
|
||||
Texture::Params p;
|
||||
p.m_allocator = GetDefaultAllocator(make_ref(&context));
|
||||
p.m_format = dp::TextureFormat::Alpha;
|
||||
p.m_format = dp::TextureFormat::Red;
|
||||
p.m_width = p.m_height = kTextureSize;
|
||||
|
||||
DummyTexture tex;
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
#include "drape/graphics_context.hpp"
|
||||
|
||||
// Testing context simulates OpenGLES2 API version.
|
||||
// Testing context simulates OpenGLES3 API version.
|
||||
class TestingGraphicsContext : public dp::GraphicsContext
|
||||
{
|
||||
public:
|
||||
|
@ -38,5 +38,5 @@ public:
|
|||
void SetCullingEnabled(bool enabled) override {}
|
||||
|
||||
private:
|
||||
dp::ApiVersion m_apiVersion = dp::ApiVersion::OpenGLES2;
|
||||
dp::ApiVersion m_apiVersion = dp::ApiVersion::OpenGLES3;
|
||||
};
|
||||
|
|
|
@ -81,7 +81,7 @@ public:
|
|||
FontTexture(m2::PointU const & size, ref_ptr<GlyphManager> glyphMng, ref_ptr<HWTextureAllocator> allocator)
|
||||
: m_index(size, glyphMng)
|
||||
{
|
||||
DynamicTextureParams const params{size, TextureFormat::Alpha, TextureFilter::Linear, true /* m_usePixelBuffer */};
|
||||
DynamicTextureParams const params{size, TextureFormat::Red, TextureFilter::Linear, true /* m_usePixelBuffer */};
|
||||
Init(allocator, make_ref(&m_index), params);
|
||||
}
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ void Framebuffer::SetSize(ref_ptr<dp::GraphicsContext> context, uint32_t width,
|
|||
m_depthStencilRef->SetSize(context, m_width, m_height);
|
||||
|
||||
auto const apiVersion = context->GetApiVersion();
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
glConst depthAttachmentId = 0;
|
||||
glConst stencilAttachmentId = 0;
|
||||
|
|
|
@ -7,67 +7,14 @@
|
|||
|
||||
namespace dp
|
||||
{
|
||||
void GLExtensionsList::Init(dp::ApiVersion apiVersion)
|
||||
void GLExtensionsList::Init()
|
||||
{
|
||||
#if defined(OMIM_OS_MOBILE)
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES2)
|
||||
{
|
||||
#ifdef OMIM_OS_ANDROID
|
||||
SetExtension(VertexArrayObject, false);
|
||||
// On some Android devices glMapBufferRange/glMapBuffer works very slow.
|
||||
// We have to substitute these functions to glBufferData/glBufferSubData.
|
||||
SetExtension(MapBuffer, false);
|
||||
SetExtension(MapBufferRange, false);
|
||||
#else
|
||||
CheckExtension(VertexArrayObject, "GL_OES_vertex_array_object");
|
||||
CheckExtension(MapBuffer, "GL_OES_mapbuffer");
|
||||
CheckExtension(MapBufferRange, "GL_EXT_map_buffer_range");
|
||||
#endif
|
||||
CheckExtension(UintIndices, "GL_OES_element_index_uint");
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef OMIM_OS_ANDROID
|
||||
SetExtension(MapBuffer, false);
|
||||
SetExtension(MapBufferRange, false);
|
||||
#else
|
||||
SetExtension(MapBuffer, true);
|
||||
SetExtension(MapBufferRange, true);
|
||||
#endif
|
||||
SetExtension(VertexArrayObject, true);
|
||||
SetExtension(UintIndices, true);
|
||||
}
|
||||
#elif defined(OMIM_OS_LINUX)
|
||||
SetExtension(MapBuffer, true);
|
||||
SetExtension(UintIndices, true);
|
||||
SetExtension(VertexArrayObject, true);
|
||||
SetExtension(MapBufferRange, true);
|
||||
#elif defined(OMIM_OS_WINDOWS)
|
||||
SetExtension(MapBuffer, true);
|
||||
SetExtension(UintIndices, true);
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES2)
|
||||
{
|
||||
SetExtension(VertexArrayObject, false);
|
||||
SetExtension(MapBufferRange, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetExtension(VertexArrayObject, true);
|
||||
SetExtension(MapBufferRange, true);
|
||||
}
|
||||
// NOTE: MapBuffer/MapBufferRange are disabled by performance reasons according to
|
||||
// https://github.com/organicmaps/organicmaps/commit/d72ab7c8cd8be0eb5a622d9d33ae943b391d5707
|
||||
SetExtension(MapBuffer, false);
|
||||
#else
|
||||
SetExtension(MapBuffer, true);
|
||||
SetExtension(UintIndices, true);
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES2)
|
||||
{
|
||||
CheckExtension(VertexArrayObject, "GL_APPLE_vertex_array_object");
|
||||
SetExtension(MapBufferRange, false);
|
||||
}
|
||||
else
|
||||
{
|
||||
SetExtension(VertexArrayObject, true);
|
||||
SetExtension(MapBufferRange, true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -14,14 +14,11 @@ class GLExtensionsList
|
|||
public:
|
||||
enum ExtensionName
|
||||
{
|
||||
VertexArrayObject,
|
||||
MapBuffer,
|
||||
UintIndices,
|
||||
MapBufferRange
|
||||
};
|
||||
|
||||
GLExtensionsList() = default;
|
||||
void Init(dp::ApiVersion apiVersion);
|
||||
void Init();
|
||||
bool IsSupported(ExtensionName extName) const;
|
||||
|
||||
private:
|
||||
|
|
|
@ -239,81 +239,26 @@ void GLFunctions::Init(dp::ApiVersion apiVersion)
|
|||
return;
|
||||
|
||||
CurrentApiVersion = apiVersion;
|
||||
ExtensionsList.Init(apiVersion);
|
||||
ExtensionsList.Init();
|
||||
s_inited = true;
|
||||
|
||||
/// VAO
|
||||
#if !defined(OMIM_OS_WINDOWS)
|
||||
if (CurrentApiVersion == dp::ApiVersion::OpenGLES2)
|
||||
{
|
||||
#if defined(OMIM_OS_MAC)
|
||||
|
||||
glGenVertexArraysFn = &glGenVertexArraysAPPLE;
|
||||
glBindVertexArrayFn = &glBindVertexArrayAPPLE;
|
||||
glDeleteVertexArrayFn = &glDeleteVertexArraysAPPLE;
|
||||
glMapBufferFn = &::glMapBuffer;
|
||||
glUnmapBufferFn = &::glUnmapBuffer;
|
||||
|
||||
#elif defined(OMIM_OS_LINUX)
|
||||
void *libhandle = dlopen("libGL.so.1", RTLD_LAZY);
|
||||
if (!libhandle)
|
||||
LOG(LCRITICAL, ("Failed to open libGL.so.1:", dlerror()));
|
||||
glGenVertexArraysFn = (TglGenVertexArraysFn)dlsym(libhandle,"glGenVertexArraysOES");
|
||||
glBindVertexArrayFn = (TglBindVertexArrayFn)dlsym(libhandle, "glBindVertexArrayOES");
|
||||
glDeleteVertexArrayFn = (TglDeleteVertexArrayFn)dlsym(libhandle,"glDeleteVertexArraysOES");
|
||||
glMapBufferFn = (TglMapBufferFn)dlsym(libhandle, "glMapBufferOES");
|
||||
glUnmapBufferFn = (TglUnmapBufferFn)dlsym(libhandle, "glUnmapBufferOES");
|
||||
glMapBufferRangeFn = (TglMapBufferRangeFn)dlsym(libhandle, "glMapBufferRangeEXT");
|
||||
glFlushMappedBufferRangeFn =
|
||||
(TglFlushMappedBufferRangeFn)dlsym(libhandle, "glFlushMappedBufferRangeEXT");
|
||||
|
||||
#elif defined(OMIM_OS_ANDROID)
|
||||
|
||||
glGenVertexArraysFn = (TglGenVertexArraysFn)eglGetProcAddress("glGenVertexArraysOES");
|
||||
glBindVertexArrayFn = (TglBindVertexArrayFn)eglGetProcAddress("glBindVertexArrayOES");
|
||||
glDeleteVertexArrayFn = (TglDeleteVertexArrayFn)eglGetProcAddress("glDeleteVertexArraysOES");
|
||||
glMapBufferFn = &::glMapBufferOES;
|
||||
glUnmapBufferFn = &::glUnmapBufferOES;
|
||||
glMapBufferRangeFn = (TglMapBufferRangeFn)eglGetProcAddress("glMapBufferRangeEXT");
|
||||
glFlushMappedBufferRangeFn =
|
||||
(TglFlushMappedBufferRangeFn)eglGetProcAddress("glFlushMappedBufferRangeEXT");
|
||||
|
||||
#elif defined(OMIM_OS_MOBILE)
|
||||
|
||||
glGenVertexArraysFn = &glGenVertexArraysOES;
|
||||
glBindVertexArrayFn = &glBindVertexArrayOES;
|
||||
glDeleteVertexArrayFn = &glDeleteVertexArraysOES;
|
||||
glMapBufferFn = &::glMapBufferOES;
|
||||
glUnmapBufferFn = &::glUnmapBufferOES;
|
||||
glMapBufferRangeFn = &::glMapBufferRangeEXT;
|
||||
glFlushMappedBufferRangeFn = &::glFlushMappedBufferRangeEXT;
|
||||
#endif // #if defined(OMIM_OS_MAC)
|
||||
}
|
||||
else if (CurrentApiVersion == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
// OpenGL ES3 api is the same for all systems, except WINDOWS.
|
||||
glGenVertexArraysFn = ::glGenVertexArrays;
|
||||
glBindVertexArrayFn = ::glBindVertexArray;
|
||||
glDeleteVertexArrayFn = ::glDeleteVertexArrays;
|
||||
glUnmapBufferFn = ::glUnmapBuffer;
|
||||
glMapBufferRangeFn = ::glMapBufferRange;
|
||||
glFlushMappedBufferRangeFn = ::glFlushMappedBufferRange;
|
||||
glGetStringiFn = ::glGetStringi;
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK(false, ("Unknown Graphics API"));
|
||||
}
|
||||
|
||||
// OpenGL ES3 api is the same for all systems, except WINDOWS.
|
||||
glGenVertexArraysFn = ::glGenVertexArrays;
|
||||
glBindVertexArrayFn = ::glBindVertexArray;
|
||||
glDeleteVertexArrayFn = ::glDeleteVertexArrays;
|
||||
glUnmapBufferFn = ::glUnmapBuffer;
|
||||
glMapBufferRangeFn = ::glMapBufferRange;
|
||||
glFlushMappedBufferRangeFn = ::glFlushMappedBufferRange;
|
||||
glGetStringiFn = ::glGetStringi;
|
||||
#else // OMIM_OS_WINDOWS
|
||||
if (ExtensionsList.IsSupported(dp::GLExtensionsList::VertexArrayObject))
|
||||
{
|
||||
glGenVertexArraysFn = LOAD_GL_FUNC(TglGenVertexArraysFn, glGenVertexArrays);
|
||||
glBindVertexArrayFn = LOAD_GL_FUNC(TglBindVertexArrayFn, glBindVertexArray);
|
||||
glDeleteVertexArrayFn = LOAD_GL_FUNC(TglDeleteVertexArrayFn, glDeleteVertexArrays);
|
||||
}
|
||||
glMapBufferFn = LOAD_GL_FUNC(TglMapBufferFn, glMapBuffer);
|
||||
glGenVertexArraysFn = LOAD_GL_FUNC(TglGenVertexArraysFn, glGenVertexArrays);
|
||||
glBindVertexArrayFn = LOAD_GL_FUNC(TglBindVertexArrayFn, glBindVertexArray);
|
||||
glDeleteVertexArrayFn = LOAD_GL_FUNC(TglDeleteVertexArrayFn, glDeleteVertexArrays);
|
||||
glUnmapBufferFn = LOAD_GL_FUNC(TglUnmapBufferFn, glUnmapBuffer);
|
||||
glMapBufferFn = LOAD_GL_FUNC(TglMapBufferFn, glMapBuffer);
|
||||
glFlushMappedBufferRangeFn = LOAD_GL_FUNC(TglFlushMappedBufferRangeFn, glFlushMappedBufferRange);
|
||||
glGetStringiFn = LOAD_GL_FUNC(TglGetStringiFn, glGetStringi);
|
||||
#endif
|
||||
|
||||
glClearColorFn = LOAD_GL_FUNC(TglClearColorFn, glClearColor);
|
||||
|
@ -393,115 +338,94 @@ void GLFunctions::Init(dp::ApiVersion apiVersion)
|
|||
|
||||
bool GLFunctions::glHasExtension(std::string const & name)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
if (CurrentApiVersion == dp::ApiVersion::OpenGLES2)
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glGetStringiFn != nullptr, ());
|
||||
GLint n = 0;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &n);
|
||||
for (GLint i = 0; i < n; i++)
|
||||
{
|
||||
char const * extensions = reinterpret_cast<char const *>(::glGetString(GL_EXTENSIONS));
|
||||
GLCHECKCALL();
|
||||
if (extensions == nullptr)
|
||||
return false;
|
||||
|
||||
char const * extName = name.c_str();
|
||||
char const * ptr = nullptr;
|
||||
while ((ptr = strstr(extensions, extName)) != nullptr)
|
||||
{
|
||||
char const * end = ptr + strlen(extName);
|
||||
if (isspace(*end) || *end == '\0')
|
||||
return true;
|
||||
|
||||
extensions = end;
|
||||
}
|
||||
}
|
||||
else if (CurrentApiVersion == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
ASSERT(glGetStringiFn != nullptr, ());
|
||||
GLint n = 0;
|
||||
glGetIntegerv(GL_NUM_EXTENSIONS, &n);
|
||||
for (GLint i = 0; i < n; i++)
|
||||
{
|
||||
std::string const extension =
|
||||
std::string(reinterpret_cast<char const *>(glGetStringiFn(GL_EXTENSIONS, i)));
|
||||
if (extension == name)
|
||||
return true;
|
||||
}
|
||||
std::string const extension =
|
||||
std::string(reinterpret_cast<char const *>(glGetStringiFn(GL_EXTENSIONS, i)));
|
||||
if (extension == name)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void GLFunctions::glClearColor(float r, float g, float b, float a)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glClearColorFn != nullptr, ());
|
||||
GLCHECK(glClearColorFn(r, g, b, a));
|
||||
}
|
||||
|
||||
void GLFunctions::glClear(uint32_t clearBits)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glClearFn != nullptr, ());
|
||||
GLCHECK(glClearFn(clearBits));
|
||||
}
|
||||
|
||||
void GLFunctions::glViewport(uint32_t x, uint32_t y, uint32_t w, uint32_t h)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glViewportFn != nullptr, ());
|
||||
GLCHECK(glViewportFn(x, y, w, h));
|
||||
}
|
||||
|
||||
void GLFunctions::glScissor(uint32_t x, uint32_t y, uint32_t w, uint32_t h)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glScissorFn != nullptr, ());
|
||||
GLCHECK(glScissorFn(x, y, w, h));
|
||||
}
|
||||
|
||||
void GLFunctions::glFlush()
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glFlushFn != nullptr, ());
|
||||
GLCHECK(glFlushFn());
|
||||
}
|
||||
|
||||
void GLFunctions::glFinish()
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glFinish());
|
||||
}
|
||||
|
||||
void GLFunctions::glFrontFace(glConst mode)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glFrontFace(mode));
|
||||
}
|
||||
|
||||
void GLFunctions::glCullFace(glConst face)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glCullFace(face));
|
||||
}
|
||||
|
||||
void GLFunctions::glStencilOpSeparate(glConst face, glConst sfail, glConst dpfail, glConst dppass)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glStencilOpSeparate(face, sfail, dpfail, dppass));
|
||||
}
|
||||
|
||||
void GLFunctions::glStencilFuncSeparate(glConst face, glConst func, int ref, uint32_t mask)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glStencilFuncSeparate(face, func, ref, mask));
|
||||
}
|
||||
|
||||
void GLFunctions::glPixelStore(glConst name, uint32_t value)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glPixelStorei(name, value));
|
||||
}
|
||||
|
||||
int32_t GLFunctions::glGetInteger(glConst pname)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLint value;
|
||||
GLCHECK(::glGetIntegerv(pname, &value));
|
||||
return (int32_t)value;
|
||||
|
@ -509,7 +433,7 @@ int32_t GLFunctions::glGetInteger(glConst pname)
|
|||
|
||||
std::string GLFunctions::glGetString(glConst pname)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
char const * str = reinterpret_cast<char const *>(::glGetString(pname));
|
||||
GLCHECKCALL();
|
||||
if (str == nullptr)
|
||||
|
@ -520,7 +444,7 @@ std::string GLFunctions::glGetString(glConst pname)
|
|||
|
||||
int32_t GLFunctions::glGetMaxLineWidth()
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLint range[2];
|
||||
GLCHECK(::glGetIntegerv(GL_ALIASED_LINE_WIDTH_RANGE, range));
|
||||
return std::max(range[0], range[1]);
|
||||
|
@ -528,7 +452,7 @@ int32_t GLFunctions::glGetMaxLineWidth()
|
|||
|
||||
int32_t GLFunctions::glGetBufferParameter(glConst target, glConst name)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLint result;
|
||||
ASSERT(glGetBufferParameterFn != nullptr, ());
|
||||
GLCHECK(glGetBufferParameterFn(target, name, &result));
|
||||
|
@ -537,19 +461,19 @@ int32_t GLFunctions::glGetBufferParameter(glConst target, glConst name)
|
|||
|
||||
void GLFunctions::glEnable(glConst mode)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glEnable(mode));
|
||||
}
|
||||
|
||||
void GLFunctions::glDisable(glConst mode)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glDisable(mode));
|
||||
}
|
||||
|
||||
void GLFunctions::glClearDepthValue(double depth)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
#if defined(OMIM_OS_IPHONE) || defined(OMIM_OS_ANDROID) || defined(OMIM_OS_LINUX)
|
||||
GLCHECK(::glClearDepthf(static_cast<GLclampf>(depth)));
|
||||
#else
|
||||
|
@ -559,32 +483,32 @@ void GLFunctions::glClearDepthValue(double depth)
|
|||
|
||||
void GLFunctions::glDepthMask(bool needWriteToDepthBuffer)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glDepthMask(convert(needWriteToDepthBuffer)));
|
||||
}
|
||||
|
||||
void GLFunctions::glDepthFunc(glConst depthFunc)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glDepthFunc(depthFunc));
|
||||
}
|
||||
|
||||
void GLFunctions::glBlendEquation(glConst function)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glBlendEquationFn != nullptr, ());
|
||||
GLCHECK(glBlendEquationFn(function));
|
||||
}
|
||||
|
||||
void GLFunctions::glBlendFunc(glConst srcFactor, glConst dstFactor)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glBlendFunc(srcFactor, dstFactor));
|
||||
}
|
||||
|
||||
bool GLFunctions::CanEnableDebugMessages()
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
if (glDebugMessageCallbackFn == nullptr)
|
||||
return false;
|
||||
if (glDebugMessageControlFn == nullptr)
|
||||
|
@ -596,7 +520,7 @@ bool GLFunctions::CanEnableDebugMessages()
|
|||
|
||||
void GLFunctions::glDebugMessageCallback(TglDebugProc messageCallback, void * userParam)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glDebugMessageCallbackFn != nullptr, ());
|
||||
GLCHECK(glDebugMessageCallbackFn(reinterpret_cast<GLDEBUGPROC>(messageCallback), userParam));
|
||||
}
|
||||
|
@ -604,14 +528,14 @@ void GLFunctions::glDebugMessageCallback(TglDebugProc messageCallback, void * us
|
|||
void GLFunctions::glDebugMessageControl(glConst source, glConst type, glConst severity,
|
||||
int32_t count, uint32_t const * ids, uint8_t enabled)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glDebugMessageControlFn != nullptr, ());
|
||||
GLCHECK(glDebugMessageControlFn(source, type, severity, count, ids, enabled));
|
||||
}
|
||||
|
||||
uint32_t GLFunctions::glGenVertexArray()
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glGenVertexArraysFn != nullptr, ());
|
||||
GLuint result = std::numeric_limits<GLuint>::max();
|
||||
GLCHECK(glGenVertexArraysFn(1, &result));
|
||||
|
@ -620,21 +544,21 @@ uint32_t GLFunctions::glGenVertexArray()
|
|||
|
||||
void GLFunctions::glBindVertexArray(uint32_t vao)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glBindVertexArrayFn != nullptr, ());
|
||||
GLCHECK(glBindVertexArrayFn(vao));
|
||||
}
|
||||
|
||||
void GLFunctions::glDeleteVertexArray(uint32_t vao)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glDeleteVertexArrayFn != nullptr, ());
|
||||
GLCHECK(glDeleteVertexArrayFn(1, &vao));
|
||||
}
|
||||
|
||||
uint32_t GLFunctions::glGenBuffer()
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glGenBuffersFn != nullptr, ());
|
||||
GLuint result = std::numeric_limits<GLuint>::max();
|
||||
GLCHECK(glGenBuffersFn(1, &result));
|
||||
|
@ -643,7 +567,7 @@ uint32_t GLFunctions::glGenBuffer()
|
|||
|
||||
void GLFunctions::glBindBuffer(uint32_t vbo, uint32_t target)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glBindBufferFn != nullptr, ());
|
||||
#ifdef DEBUG
|
||||
std::lock_guard<std::mutex> guard(g_boundBuffersMutex);
|
||||
|
@ -654,7 +578,7 @@ void GLFunctions::glBindBuffer(uint32_t vbo, uint32_t target)
|
|||
|
||||
void GLFunctions::glDeleteBuffer(uint32_t vbo)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glDeleteBuffersFn != nullptr, ());
|
||||
#ifdef DEBUG
|
||||
std::lock_guard<std::mutex> guard(g_boundBuffersMutex);
|
||||
|
@ -666,21 +590,21 @@ void GLFunctions::glDeleteBuffer(uint32_t vbo)
|
|||
|
||||
void GLFunctions::glBufferData(glConst target, uint32_t size, void const * data, glConst usage)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glBufferDataFn != nullptr, ());
|
||||
GLCHECK(glBufferDataFn(target, size, data, usage));
|
||||
}
|
||||
|
||||
void GLFunctions::glBufferSubData(glConst target, uint32_t size, void const * data, uint32_t offset)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glBufferSubDataFn != nullptr, ());
|
||||
GLCHECK(glBufferSubDataFn(target, offset, size, data));
|
||||
}
|
||||
|
||||
void * GLFunctions::glMapBuffer(glConst target, glConst access)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glMapBufferFn != nullptr, ());
|
||||
void * result = glMapBufferFn(target, access);
|
||||
GLCHECKCALL();
|
||||
|
@ -689,7 +613,7 @@ void * GLFunctions::glMapBuffer(glConst target, glConst access)
|
|||
|
||||
void GLFunctions::glUnmapBuffer(glConst target)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glUnmapBufferFn != nullptr, ());
|
||||
VERIFY(glUnmapBufferFn(target) == GL_TRUE, ());
|
||||
GLCHECKCALL();
|
||||
|
@ -698,7 +622,7 @@ void GLFunctions::glUnmapBuffer(glConst target)
|
|||
void * GLFunctions::glMapBufferRange(glConst target, uint32_t offset, uint32_t length,
|
||||
glConst access)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glMapBufferRangeFn != nullptr, ());
|
||||
void * result = glMapBufferRangeFn(target, offset, length, access);
|
||||
GLCHECKCALL();
|
||||
|
@ -707,14 +631,14 @@ void * GLFunctions::glMapBufferRange(glConst target, uint32_t offset, uint32_t l
|
|||
|
||||
void GLFunctions::glFlushMappedBufferRange(glConst target, uint32_t offset, uint32_t length)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glFlushMappedBufferRangeFn != nullptr, ());
|
||||
GLCHECK(glFlushMappedBufferRangeFn(target, offset, length));
|
||||
}
|
||||
|
||||
uint32_t GLFunctions::glCreateShader(glConst type)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glCreateShaderFn != nullptr, ());
|
||||
GLuint result = glCreateShaderFn(type);
|
||||
GLCHECKCALL();
|
||||
|
@ -723,7 +647,7 @@ uint32_t GLFunctions::glCreateShader(glConst type)
|
|||
|
||||
void GLFunctions::glShaderSource(uint32_t shaderID, std::string const & src, std::string const & defines)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glShaderSourceFn != nullptr, ());
|
||||
|
||||
std::string fullSrc;
|
||||
|
@ -746,7 +670,7 @@ void GLFunctions::glShaderSource(uint32_t shaderID, std::string const & src, std
|
|||
|
||||
bool GLFunctions::glCompileShader(uint32_t shaderID, std::string & errorLog)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glCompileShaderFn != nullptr, ());
|
||||
ASSERT(glGetShaderivFn != nullptr, ());
|
||||
ASSERT(glGetShaderInfoLogFn != nullptr, ());
|
||||
|
@ -766,14 +690,14 @@ bool GLFunctions::glCompileShader(uint32_t shaderID, std::string & errorLog)
|
|||
|
||||
void GLFunctions::glDeleteShader(uint32_t shaderID)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glDeleteShaderFn != nullptr, ());
|
||||
GLCHECK(glDeleteBuffersFn(1, &shaderID));
|
||||
}
|
||||
|
||||
uint32_t GLFunctions::glCreateProgram()
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glCreateProgramFn != nullptr, ());
|
||||
GLuint result = glCreateProgramFn();
|
||||
GLCHECKCALL();
|
||||
|
@ -782,21 +706,21 @@ uint32_t GLFunctions::glCreateProgram()
|
|||
|
||||
void GLFunctions::glAttachShader(uint32_t programID, uint32_t shaderID)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glAttachShaderFn != nullptr, ());
|
||||
GLCHECK(glAttachShaderFn(programID, shaderID));
|
||||
}
|
||||
|
||||
void GLFunctions::glDetachShader(uint32_t programID, uint32_t shaderID)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glDetachShaderFn != nullptr, ());
|
||||
GLCHECK(glDetachShaderFn(programID, shaderID));
|
||||
}
|
||||
|
||||
bool GLFunctions::glLinkProgram(uint32_t programID, std::string & errorLog)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glLinkProgramFn != nullptr, ());
|
||||
ASSERT(glGetProgramivFn != nullptr, ());
|
||||
ASSERT(glGetProgramInfoLogFn != nullptr, ());
|
||||
|
@ -817,21 +741,21 @@ bool GLFunctions::glLinkProgram(uint32_t programID, std::string & errorLog)
|
|||
|
||||
void GLFunctions::glDeleteProgram(uint32_t programID)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glDeleteProgramFn != nullptr, ());
|
||||
GLCHECK(glDeleteProgramFn(programID));
|
||||
}
|
||||
|
||||
void GLFunctions::glUseProgram(uint32_t programID)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glUseProgramFn != nullptr, ());
|
||||
GLCHECK(glUseProgramFn(programID));
|
||||
}
|
||||
|
||||
int8_t GLFunctions::glGetAttribLocation(uint32_t programID, std::string const & name)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glGetAttribLocationFn != nullptr, ());
|
||||
int result = glGetAttribLocationFn(programID, name.c_str());
|
||||
GLCHECKCALL();
|
||||
|
@ -841,14 +765,14 @@ int8_t GLFunctions::glGetAttribLocation(uint32_t programID, std::string const &
|
|||
|
||||
void GLFunctions::glBindAttribLocation(uint32_t programID, uint8_t index, std::string const & name)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glBindAttribLocationFn != nullptr, ());
|
||||
GLCHECK(glBindAttribLocationFn(programID, index, name.c_str()));
|
||||
}
|
||||
|
||||
void GLFunctions::glEnableVertexAttribute(int attributeLocation)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glEnableVertexAttributeFn != nullptr, ());
|
||||
GLCHECK(glEnableVertexAttributeFn(attributeLocation));
|
||||
}
|
||||
|
@ -856,7 +780,7 @@ void GLFunctions::glEnableVertexAttribute(int attributeLocation)
|
|||
void GLFunctions::glVertexAttributePointer(int attrLocation, uint32_t count, glConst type,
|
||||
bool needNormalize, uint32_t stride, uint32_t offset)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glVertexAttributePointerFn != nullptr, ());
|
||||
GLCHECK(glVertexAttributePointerFn(attrLocation, count, type, convert(needNormalize), stride,
|
||||
reinterpret_cast<void *>(offset)));
|
||||
|
@ -865,7 +789,7 @@ void GLFunctions::glVertexAttributePointer(int attrLocation, uint32_t count, glC
|
|||
void GLFunctions::glGetActiveUniform(uint32_t programID, uint32_t uniformIndex,
|
||||
int32_t * uniformSize, glConst * type, std::string & name)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glGetActiveUniformFn != nullptr, ());
|
||||
GLchar buff[256];
|
||||
GLCHECK(glGetActiveUniformFn(programID, uniformIndex, ARRAY_SIZE(buff), nullptr, uniformSize,
|
||||
|
@ -875,17 +799,17 @@ void GLFunctions::glGetActiveUniform(uint32_t programID, uint32_t uniformIndex,
|
|||
|
||||
int8_t GLFunctions::glGetUniformLocation(uint32_t programID, std::string const & name)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glGetUniformLocationFn != nullptr, ());
|
||||
int result = glGetUniformLocationFn(programID, name.c_str());
|
||||
GLCHECKCALL();
|
||||
ASSERT(result != -1, ());
|
||||
ASSERT(result != -1, (name));
|
||||
return static_cast<int8_t>(result);
|
||||
}
|
||||
|
||||
void GLFunctions::glUniformValuei(int8_t location, int32_t v)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glUniform1iFn != nullptr, ());
|
||||
ASSERT(location != -1, ());
|
||||
GLCHECK(glUniform1iFn(location, v));
|
||||
|
@ -893,7 +817,7 @@ void GLFunctions::glUniformValuei(int8_t location, int32_t v)
|
|||
|
||||
void GLFunctions::glUniformValuei(int8_t location, int32_t v1, int32_t v2)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glUniform2iFn != nullptr, ());
|
||||
ASSERT(location != -1, ());
|
||||
GLCHECK(glUniform2iFn(location, v1, v2));
|
||||
|
@ -901,7 +825,7 @@ void GLFunctions::glUniformValuei(int8_t location, int32_t v1, int32_t v2)
|
|||
|
||||
void GLFunctions::glUniformValuei(int8_t location, int32_t v1, int32_t v2, int32_t v3)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glUniform3iFn != nullptr, ());
|
||||
ASSERT(location != -1, ());
|
||||
GLCHECK(glUniform3iFn(location, v1, v2, v3));
|
||||
|
@ -909,7 +833,7 @@ void GLFunctions::glUniformValuei(int8_t location, int32_t v1, int32_t v2, int32
|
|||
|
||||
void GLFunctions::glUniformValuei(int8_t location, int32_t v1, int32_t v2, int32_t v3, int32_t v4)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glUniform4iFn != nullptr, ());
|
||||
ASSERT(location != -1, ());
|
||||
GLCHECK(glUniform4iFn(location, v1, v2, v3, v4));
|
||||
|
@ -917,7 +841,7 @@ void GLFunctions::glUniformValuei(int8_t location, int32_t v1, int32_t v2, int32
|
|||
|
||||
void GLFunctions::glUniformValueiv(int8_t location, int32_t * v, uint32_t size)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glUniform1ivFn != nullptr, ());
|
||||
ASSERT(location != -1, ());
|
||||
GLCHECK(glUniform1ivFn(location, size, v));
|
||||
|
@ -925,7 +849,7 @@ void GLFunctions::glUniformValueiv(int8_t location, int32_t * v, uint32_t size)
|
|||
|
||||
void GLFunctions::glUniformValuef(int8_t location, float v)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glUniform1fFn != nullptr, ());
|
||||
ASSERT(location != -1, ());
|
||||
GLCHECK(glUniform1fFn(location, v));
|
||||
|
@ -933,7 +857,7 @@ void GLFunctions::glUniformValuef(int8_t location, float v)
|
|||
|
||||
void GLFunctions::glUniformValuef(int8_t location, float v1, float v2)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glUniform2fFn != nullptr, ());
|
||||
ASSERT(location != -1, ());
|
||||
GLCHECK(glUniform2fFn(location, v1, v2));
|
||||
|
@ -941,7 +865,7 @@ void GLFunctions::glUniformValuef(int8_t location, float v1, float v2)
|
|||
|
||||
void GLFunctions::glUniformValuef(int8_t location, float v1, float v2, float v3)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glUniform3fFn != nullptr, ());
|
||||
ASSERT(location != -1, ());
|
||||
GLCHECK(glUniform3fFn(location, v1, v2, v3));
|
||||
|
@ -949,7 +873,7 @@ void GLFunctions::glUniformValuef(int8_t location, float v1, float v2, float v3)
|
|||
|
||||
void GLFunctions::glUniformValuef(int8_t location, float v1, float v2, float v3, float v4)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glUniform4fFn != nullptr, ());
|
||||
ASSERT(location != -1, ());
|
||||
GLCHECK(glUniform4fFn(location, v1, v2, v3, v4));
|
||||
|
@ -957,7 +881,7 @@ void GLFunctions::glUniformValuef(int8_t location, float v1, float v2, float v3,
|
|||
|
||||
void GLFunctions::glUniformValuefv(int8_t location, float * v, uint32_t size)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glUniform1fvFn != nullptr, ());
|
||||
ASSERT(location != -1, ());
|
||||
GLCHECK(glUniform1fvFn(location, size, v));
|
||||
|
@ -965,7 +889,7 @@ void GLFunctions::glUniformValuefv(int8_t location, float * v, uint32_t size)
|
|||
|
||||
void GLFunctions::glUniformMatrix4x4Value(int8_t location, float const * values)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glUniformMatrix4fvFn != nullptr, ());
|
||||
ASSERT(location != -1, ());
|
||||
GLCHECK(glUniformMatrix4fvFn(location, 1, GL_FALSE, values));
|
||||
|
@ -973,7 +897,7 @@ void GLFunctions::glUniformMatrix4x4Value(int8_t location, float const * values)
|
|||
|
||||
uint32_t GLFunctions::glGetCurrentProgram()
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLint programIndex = 0;
|
||||
GLCHECK(glGetIntegerv(GL_CURRENT_PROGRAM, &programIndex));
|
||||
ASSERT_GREATER_OR_EQUAL(programIndex, 0, ());
|
||||
|
@ -982,7 +906,7 @@ uint32_t GLFunctions::glGetCurrentProgram()
|
|||
|
||||
int32_t GLFunctions::glGetProgramiv(uint32_t program, glConst paramName)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glGetProgramivFn != nullptr, ());
|
||||
GLint paramValue = 0;
|
||||
GLCHECK(glGetProgramivFn(program, paramName, ¶mValue));
|
||||
|
@ -991,14 +915,14 @@ int32_t GLFunctions::glGetProgramiv(uint32_t program, glConst paramName)
|
|||
|
||||
void GLFunctions::glActiveTexture(glConst texBlock)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glActiveTextureFn != nullptr, ());
|
||||
GLCHECK(glActiveTextureFn(texBlock));
|
||||
}
|
||||
|
||||
uint32_t GLFunctions::glGenTexture()
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLuint result = std::numeric_limits<GLuint>::max();
|
||||
GLCHECK(::glGenTextures(1, &result));
|
||||
return result;
|
||||
|
@ -1006,20 +930,20 @@ uint32_t GLFunctions::glGenTexture()
|
|||
|
||||
void GLFunctions::glDeleteTexture(uint32_t id)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glDeleteTextures(1, &id));
|
||||
}
|
||||
|
||||
void GLFunctions::glBindTexture(uint32_t textureID)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glBindTexture(GL_TEXTURE_2D, textureID));
|
||||
}
|
||||
|
||||
void GLFunctions::glTexImage2D(int width, int height, glConst layout, glConst pixelType,
|
||||
void const * data)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
// In OpenGL ES3:
|
||||
// - we can't create unsized GL_RED texture, so we use GL_R8;
|
||||
// - we can't create unsized GL_RG texture, so we use GL_RG8;
|
||||
|
@ -1058,20 +982,20 @@ void GLFunctions::glTexImage2D(int width, int height, glConst layout, glConst pi
|
|||
void GLFunctions::glTexSubImage2D(int x, int y, int width, int height, glConst layout,
|
||||
glConst pixelType, void const * data)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, width, height, layout, pixelType, data));
|
||||
}
|
||||
|
||||
void GLFunctions::glTexParameter(glConst param, glConst value)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glTexParameteri(GL_TEXTURE_2D, param, value));
|
||||
}
|
||||
|
||||
void GLFunctions::glDrawElements(glConst primitive, uint32_t sizeOfIndex, uint32_t indexCount,
|
||||
uint32_t startIndex)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glDrawElements(primitive, indexCount,
|
||||
sizeOfIndex == sizeof(uint32_t) ? GL_UNSIGNED_INT : GL_UNSIGNED_SHORT,
|
||||
reinterpret_cast<GLvoid *>(startIndex * sizeOfIndex)));
|
||||
|
@ -1079,41 +1003,41 @@ void GLFunctions::glDrawElements(glConst primitive, uint32_t sizeOfIndex, uint32
|
|||
|
||||
void GLFunctions::glDrawArrays(glConst mode, int32_t first, uint32_t count)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glDrawArrays(mode, first, count));
|
||||
}
|
||||
|
||||
void GLFunctions::glGenFramebuffer(uint32_t * fbo)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glGenFramebuffersFn != nullptr, ());
|
||||
GLCHECK(glGenFramebuffersFn(1, fbo));
|
||||
}
|
||||
|
||||
void GLFunctions::glDeleteFramebuffer(uint32_t * fbo)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glDeleteFramebuffersFn != nullptr, ());
|
||||
GLCHECK(glDeleteFramebuffersFn(1, fbo));
|
||||
}
|
||||
|
||||
void GLFunctions::glFramebufferTexture2D(glConst attachment, glConst texture)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glFramebufferTexture2DFn != nullptr, ());
|
||||
GLCHECK(glFramebufferTexture2DFn(GL_FRAMEBUFFER, attachment, GL_TEXTURE_2D, texture, 0));
|
||||
}
|
||||
|
||||
void GLFunctions::glBindFramebuffer(uint32_t fbo)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glBindFramebufferFn != nullptr, ());
|
||||
GLCHECK(glBindFramebufferFn(GL_FRAMEBUFFER, fbo));
|
||||
}
|
||||
|
||||
uint32_t GLFunctions::glCheckFramebufferStatus()
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
ASSERT(glCheckFramebufferStatusFn != nullptr, ());
|
||||
uint32_t const result = glCheckFramebufferStatusFn(GL_FRAMEBUFFER);
|
||||
GLCHECKCALL();
|
||||
|
@ -1122,7 +1046,7 @@ uint32_t GLFunctions::glCheckFramebufferStatus()
|
|||
|
||||
void GLFunctions::glLineWidth(uint32_t value)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLCHECK(::glLineWidth(static_cast<float>(value)));
|
||||
}
|
||||
|
||||
|
@ -1143,7 +1067,7 @@ std::string GetGLError(GLenum error)
|
|||
|
||||
void CheckGLError(base::SrcPoint const & srcPoint)
|
||||
{
|
||||
ASSERT_NOT_EQUAL(GLFunctions::CurrentApiVersion, dp::ApiVersion::Invalid, ());
|
||||
ASSERT_EQUAL(GLFunctions::CurrentApiVersion, dp::ApiVersion::OpenGLES3, ());
|
||||
GLenum result = glGetError();
|
||||
while (result != GL_NO_ERROR)
|
||||
{
|
||||
|
|
|
@ -23,26 +23,14 @@ GLGpuProgram::GLGpuProgram(std::string const & programName,
|
|||
if (!GLFunctions::glLinkProgram(m_programID, errorLog))
|
||||
LOG(LERROR, ("Program ", programName, " link error = ", errorLog));
|
||||
|
||||
// On Tegra3 glGetActiveUniform isn't work if you detach shaders after linking.
|
||||
LoadUniformLocations();
|
||||
|
||||
// On Tegra2 we cannot detach shaders at all.
|
||||
// https://devtalk.nvidia.com/default/topic/528941/alpha-blending-not-working-on-t20-and-t30-under-ice-cream-sandwich/
|
||||
if (!SupportManager::Instance().IsTegraDevice())
|
||||
{
|
||||
GLFunctions::glDetachShader(m_programID, m_vertexShader->GetID());
|
||||
GLFunctions::glDetachShader(m_programID, m_fragmentShader->GetID());
|
||||
}
|
||||
GLFunctions::glDetachShader(m_programID, m_vertexShader->GetID());
|
||||
GLFunctions::glDetachShader(m_programID, m_fragmentShader->GetID());
|
||||
}
|
||||
|
||||
GLGpuProgram::~GLGpuProgram()
|
||||
{
|
||||
if (SupportManager::Instance().IsTegraDevice())
|
||||
{
|
||||
GLFunctions::glDetachShader(m_programID, m_vertexShader->GetID());
|
||||
GLFunctions::glDetachShader(m_programID, m_fragmentShader->GetID());
|
||||
}
|
||||
|
||||
GLFunctions::glDeleteProgram(m_programID);
|
||||
}
|
||||
|
||||
|
@ -107,7 +95,7 @@ void GLGpuProgram::LoadUniformLocations()
|
|||
std::string name;
|
||||
GLFunctions::glGetActiveUniform(m_programID, static_cast<uint32_t>(i), &size, &info.m_type, name);
|
||||
CHECK(kSupportedTypes.find(info.m_type) != kSupportedTypes.cend(),
|
||||
("Used uniform has unsupported type. Program =", m_programName, "Type =", info.m_type));
|
||||
("Used uniform has unsupported type. Program =", m_programName, "; Type =", info.m_type, "; Name =", name));
|
||||
|
||||
info.m_location = GLFunctions::glGetUniformLocation(m_programID, name);
|
||||
m_uniforms[name] = std::move(info);
|
||||
|
|
|
@ -87,26 +87,17 @@ void * GPUBuffer::Map(uint32_t elementOffset, uint32_t elementCount)
|
|||
m_isMapped = true;
|
||||
#endif
|
||||
|
||||
if (GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES2)
|
||||
if (!IsMapBufferSupported())
|
||||
{
|
||||
m_mappingOffset = elementOffset;
|
||||
return IsMapBufferSupported() ? GLFunctions::glMapBuffer(glTarget(m_t)) : nullptr;
|
||||
return nullptr;
|
||||
}
|
||||
else if (GLFunctions::CurrentApiVersion == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
if (!IsMapBufferSupported())
|
||||
{
|
||||
m_mappingOffset = elementOffset;
|
||||
return nullptr;
|
||||
}
|
||||
m_mappingOffset = 0;
|
||||
uint32_t const elementSize = GetElementSize();
|
||||
uint32_t const byteOffset = elementOffset * elementSize;
|
||||
uint32_t const byteCount = elementCount * elementSize;
|
||||
return GLFunctions::glMapBufferRange(glTarget(m_t), byteOffset, byteCount,
|
||||
gl_const::GLWriteBufferBit);
|
||||
}
|
||||
return nullptr;
|
||||
m_mappingOffset = 0;
|
||||
uint32_t const elementSize = GetElementSize();
|
||||
uint32_t const byteOffset = elementOffset * elementSize;
|
||||
uint32_t const byteCount = elementCount * elementSize;
|
||||
return GLFunctions::glMapBufferRange(glTarget(m_t), byteOffset, byteCount,
|
||||
gl_const::GLWriteBufferBit);
|
||||
}
|
||||
|
||||
void GPUBuffer::UpdateData(void * gpuPtr, void const * data, uint32_t elementOffset,
|
||||
|
|
|
@ -36,7 +36,7 @@ void UnpackFormat(ref_ptr<dp::GraphicsContext> context, TextureFormat format,
|
|||
glConst & layout, glConst & pixelType)
|
||||
{
|
||||
auto const apiVersion = context->GetApiVersion();
|
||||
CHECK(apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3, ());
|
||||
CHECK(apiVersion == dp::ApiVersion::OpenGLES3, ());
|
||||
|
||||
switch (format)
|
||||
{
|
||||
|
@ -45,21 +45,17 @@ void UnpackFormat(ref_ptr<dp::GraphicsContext> context, TextureFormat format,
|
|||
pixelType = gl_const::GL8BitOnChannel;
|
||||
return;
|
||||
|
||||
case TextureFormat::Alpha:
|
||||
// On OpenGL ES3 GLAlpha is not supported, we use GLRed instead.
|
||||
layout = apiVersion == dp::ApiVersion::OpenGLES2 ? gl_const::GLAlpha : gl_const::GLRed;
|
||||
case TextureFormat::Red:
|
||||
layout = gl_const::GLRed;
|
||||
pixelType = gl_const::GL8BitOnChannel;
|
||||
return;
|
||||
|
||||
case TextureFormat::RedGreen:
|
||||
// On OpenGL ES2 2-channel textures are not supported.
|
||||
layout = (apiVersion == dp::ApiVersion::OpenGLES2) ? gl_const::GLRGBA : gl_const::GLRedGreen;
|
||||
layout = gl_const::GLRedGreen;
|
||||
pixelType = gl_const::GL8BitOnChannel;
|
||||
return;
|
||||
|
||||
case TextureFormat::DepthStencil:
|
||||
// OpenGLES2 does not support texture-based depth-stencil.
|
||||
CHECK(apiVersion != dp::ApiVersion::OpenGLES2, ());
|
||||
layout = gl_const::GLDepthStencil;
|
||||
pixelType = gl_const::GLUnsignedInt24_8Type;
|
||||
return;
|
||||
|
|
|
@ -61,7 +61,7 @@ CVPixelBufferRef HWTextureAllocatorApple::CVCreatePixelBuffer(uint32_t width, ui
|
|||
cvRetval = CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_32BGRA,
|
||||
attrsRef, &result);
|
||||
break;
|
||||
case dp::TextureFormat::Alpha:
|
||||
case dp::TextureFormat::Red:
|
||||
cvRetval = CVPixelBufferCreate(kCFAllocatorDefault, width, height, kCVPixelFormatType_OneComponent8,
|
||||
attrsRef, &result);
|
||||
break;
|
||||
|
|
|
@ -56,7 +56,7 @@ void const * IndexStorage::GetRawConst() const
|
|||
bool IndexStorage::IsSupported32bit()
|
||||
{
|
||||
// We do not use 32-bit indices now to reduce size of index buffers.
|
||||
static bool const supports32Bit = false;//GLFunctions::ExtensionsList.IsSupported(GLExtensionsList::UintIndices);
|
||||
static bool const supports32Bit = false;
|
||||
return supports32Bit;
|
||||
}
|
||||
|
||||
|
|
|
@ -36,13 +36,8 @@ public:
|
|||
{
|
||||
UNUSED_VALUE(context);
|
||||
|
||||
bool const isVAOSupported =
|
||||
GLFunctions::ExtensionsList.IsSupported(dp::GLExtensionsList::VertexArrayObject);
|
||||
if (isVAOSupported)
|
||||
{
|
||||
m_VAO = GLFunctions::glGenVertexArray();
|
||||
GLFunctions::glBindVertexArray(m_VAO);
|
||||
}
|
||||
m_VAO = GLFunctions::glGenVertexArray();
|
||||
GLFunctions::glBindVertexArray(m_VAO);
|
||||
|
||||
for (auto & buffer : m_mesh->m_buffers)
|
||||
{
|
||||
|
@ -64,23 +59,19 @@ public:
|
|||
m_mesh->m_indices.data(), gl_const::GLStaticDraw);
|
||||
}
|
||||
|
||||
if (isVAOSupported)
|
||||
ref_ptr<dp::GLGpuProgram> p = program;
|
||||
for (auto const & attribute : buffer->m_attributes)
|
||||
{
|
||||
ref_ptr<dp::GLGpuProgram> p = program;
|
||||
for (auto const & attribute : buffer->m_attributes)
|
||||
{
|
||||
int8_t const attributePosition = p->GetAttributeLocation(attribute.m_attributeName);
|
||||
ASSERT_NOT_EQUAL(attributePosition, -1, ());
|
||||
GLFunctions::glEnableVertexAttribute(attributePosition);
|
||||
GLFunctions::glVertexAttributePointer(attributePosition, attribute.m_componentsCount,
|
||||
attribute.m_type, false, buffer->GetStrideInBytes(),
|
||||
attribute.m_offset);
|
||||
}
|
||||
int8_t const attributePosition = p->GetAttributeLocation(attribute.m_attributeName);
|
||||
ASSERT_NOT_EQUAL(attributePosition, -1, ());
|
||||
GLFunctions::glEnableVertexAttribute(attributePosition);
|
||||
GLFunctions::glVertexAttributePointer(attributePosition, attribute.m_componentsCount,
|
||||
attribute.m_type, false, buffer->GetStrideInBytes(),
|
||||
attribute.m_offset);
|
||||
}
|
||||
}
|
||||
|
||||
if (isVAOSupported)
|
||||
GLFunctions::glBindVertexArray(0);
|
||||
GLFunctions::glBindVertexArray(0);
|
||||
GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer);
|
||||
if (!m_mesh->m_indices.empty())
|
||||
GLFunctions::glBindBuffer(0, gl_const::GLElementArrayBuffer);
|
||||
|
@ -134,34 +125,12 @@ public:
|
|||
|
||||
void Bind(ref_ptr<dp::GpuProgram> program) override
|
||||
{
|
||||
if (GLFunctions::ExtensionsList.IsSupported(dp::GLExtensionsList::VertexArrayObject))
|
||||
{
|
||||
GLFunctions::glBindVertexArray(m_VAO);
|
||||
return;
|
||||
}
|
||||
|
||||
ref_ptr<dp::GLGpuProgram> p = program;
|
||||
for (auto const & buffer : m_mesh->m_buffers)
|
||||
{
|
||||
GLFunctions::glBindBuffer(buffer->m_bufferId, gl_const::GLArrayBuffer);
|
||||
if (m_indexBuffer != 0)
|
||||
GLFunctions::glBindBuffer(m_indexBuffer, gl_const::GLElementArrayBuffer);
|
||||
for (auto const & attribute : buffer->m_attributes)
|
||||
{
|
||||
int8_t const attributePosition = p->GetAttributeLocation(attribute.m_attributeName);
|
||||
ASSERT_NOT_EQUAL(attributePosition, -1, ());
|
||||
GLFunctions::glEnableVertexAttribute(attributePosition);
|
||||
GLFunctions::glVertexAttributePointer(attributePosition, attribute.m_componentsCount,
|
||||
attribute.m_type, false, buffer->GetStrideInBytes(),
|
||||
attribute.m_offset);
|
||||
}
|
||||
}
|
||||
GLFunctions::glBindVertexArray(m_VAO);
|
||||
}
|
||||
|
||||
void Unbind() override
|
||||
{
|
||||
if (GLFunctions::ExtensionsList.IsSupported(dp::GLExtensionsList::VertexArrayObject))
|
||||
GLFunctions::glBindVertexArray(0);
|
||||
GLFunctions::glBindVertexArray(0);
|
||||
GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer);
|
||||
if (m_indexBuffer != 0)
|
||||
GLFunctions::glBindBuffer(0, gl_const::GLElementArrayBuffer);
|
||||
|
@ -197,7 +166,7 @@ MeshObject::MeshObject(ref_ptr<dp::GraphicsContext> context, DrawPrimitive drawP
|
|||
, m_debugName(debugName)
|
||||
{
|
||||
auto const apiVersion = context->GetApiVersion();
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
InitForOpenGL();
|
||||
}
|
||||
|
|
|
@ -25,7 +25,7 @@ MTLPixelFormat UnpackFormat(TextureFormat format)
|
|||
switch (format)
|
||||
{
|
||||
case TextureFormat::RGBA8: return MTLPixelFormatRGBA8Unorm;
|
||||
case TextureFormat::Alpha: return MTLPixelFormatA8Unorm;
|
||||
case TextureFormat::Red: return MTLPixelFormatA8Unorm; // TODO: change to R8, fix shaders
|
||||
case TextureFormat::RedGreen: return MTLPixelFormatRG8Unorm;
|
||||
case TextureFormat::DepthStencil: return MTLPixelFormatDepth32Float_Stencil8;
|
||||
case TextureFormat::Depth: return MTLPixelFormatDepth32Float;
|
||||
|
|
|
@ -30,7 +30,7 @@ void AlphaBlendingState::Apply(ref_ptr<GraphicsContext> context)
|
|||
{
|
||||
// For Metal Rendering these settings must be set in the pipeline state.
|
||||
auto const apiVersion = context->GetApiVersion();
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
GLFunctions::glBlendEquation(gl_const::GLAddBlend);
|
||||
GLFunctions::glBlendFunc(gl_const::GLSrcAlpha, gl_const::GLOneMinusSrcAlpha);
|
||||
|
@ -45,7 +45,7 @@ void Blending::Apply(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> progr
|
|||
{
|
||||
// For Metal Rendering these settings must be set in the pipeline state.
|
||||
auto const apiVersion = context->GetApiVersion();
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
if (m_isEnabled)
|
||||
GLFunctions::glEnable(gl_const::GLBlending);
|
||||
|
@ -216,7 +216,7 @@ void TextureState::ApplyTextures(ref_ptr<GraphicsContext> context, RenderState c
|
|||
{
|
||||
m_usedSlots = 0;
|
||||
auto const apiVersion = context->GetApiVersion();
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
ref_ptr<dp::GLGpuProgram> p = program;
|
||||
for (auto const & texture : state.GetTextures())
|
||||
|
@ -324,7 +324,7 @@ void ApplyState(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> program, R
|
|||
|
||||
if (state.GetDrawAsLine())
|
||||
{
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
ASSERT_GREATER_OR_EQUAL(state.GetLineWidth(), 0, ());
|
||||
GLFunctions::glLineWidth(static_cast<uint32_t>(state.GetLineWidth()));
|
||||
|
|
|
@ -175,7 +175,7 @@ ref_ptr<Texture::ResourceInfo> StipplePenIndex::MapResource(StipplePenKey const
|
|||
|
||||
void StipplePenIndex::UploadResources(ref_ptr<dp::GraphicsContext> context, ref_ptr<Texture> texture)
|
||||
{
|
||||
ASSERT(texture->GetFormat() == dp::TextureFormat::Alpha, ());
|
||||
ASSERT(texture->GetFormat() == dp::TextureFormat::Red, ());
|
||||
TPendingNodes pendingNodes;
|
||||
{
|
||||
std::lock_guard<std::mutex> g(m_lock);
|
||||
|
|
|
@ -138,7 +138,7 @@ public:
|
|||
StipplePenTexture(m2::PointU const & size, ref_ptr<HWTextureAllocator> allocator)
|
||||
: m_index(size)
|
||||
{
|
||||
TBase::DynamicTextureParams params{size, TextureFormat::Alpha, TextureFilter::Nearest,
|
||||
TBase::DynamicTextureParams params{size, TextureFormat::Red, TextureFilter::Nearest,
|
||||
false /* m_usePixelBuffer */};
|
||||
TBase::Init(allocator, make_ref(&m_index), params);
|
||||
}
|
||||
|
|
|
@ -32,31 +32,8 @@ void SupportManager::Init(ref_ptr<GraphicsContext> context)
|
|||
m_rendererVersion = context->GetRendererVersion();
|
||||
LOG(LINFO, ("Renderer =", m_rendererName, "| Api =", context->GetApiVersion(), "| Version =", m_rendererVersion));
|
||||
|
||||
m_isSamsungGoogleNexus = (m_rendererName == "PowerVR SGX 540" &&
|
||||
m_rendererVersion.find("GOOGLENEXUS.ED945322") != std::string::npos);
|
||||
if (m_isSamsungGoogleNexus)
|
||||
LOG(LINFO, ("Samsung Google Nexus detected."));
|
||||
|
||||
if (m_rendererName.find("Adreno") != std::string::npos)
|
||||
{
|
||||
std::array<std::string_view, 5> constexpr models = { "200", "203", "205", "220", "225" };
|
||||
for (auto const & model : models)
|
||||
{
|
||||
if (m_rendererName.find(model) != std::string::npos)
|
||||
{
|
||||
LOG(LINFO, ("Adreno 200 device detected."));
|
||||
m_isAdreno200 = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
m_isTegra = (m_rendererName.find("Tegra") != std::string::npos);
|
||||
if (m_isTegra)
|
||||
LOG(LINFO, ("NVidia Tegra device detected."));
|
||||
|
||||
auto const apiVersion = context->GetApiVersion();
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
m_maxLineWidth = static_cast<float>(std::max(1, GLFunctions::glGetMaxLineWidth()));
|
||||
m_maxTextureSize = static_cast<uint32_t>(GLFunctions::glGetInteger(gl_const::GLMaxTextureSize));
|
||||
|
|
|
@ -26,9 +26,6 @@ public:
|
|||
// reinitialization.
|
||||
void Init(ref_ptr<GraphicsContext> context);
|
||||
|
||||
bool IsSamsungGoogleNexus() const { return m_isSamsungGoogleNexus; }
|
||||
bool IsAdreno200Device() const { return m_isAdreno200; }
|
||||
bool IsTegraDevice() const { return m_isTegra; }
|
||||
bool IsAntialiasingEnabledByDefault() const { return m_isAntialiasingEnabledByDefault; }
|
||||
|
||||
float GetMaxLineWidth() const { return m_maxLineWidth; }
|
||||
|
@ -50,9 +47,6 @@ private:
|
|||
|
||||
std::string m_rendererName;
|
||||
std::string m_rendererVersion;
|
||||
bool m_isSamsungGoogleNexus = false;
|
||||
bool m_isAdreno200 = false;
|
||||
bool m_isTegra = false;
|
||||
bool m_isAntialiasingEnabledByDefault = false;
|
||||
|
||||
float m_maxLineWidth = 1;
|
||||
|
|
|
@ -183,7 +183,7 @@ bool TextureManager::UpdateDynamicTextures(ref_ptr<dp::GraphicsContext> context)
|
|||
if (m_nothingToUpload.test_and_set())
|
||||
{
|
||||
auto const apiVersion = context->GetApiVersion();
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
// For some reasons OpenGL can not update textures immediately.
|
||||
// Here we use some timeout to prevent rendering frozening.
|
||||
|
@ -302,7 +302,7 @@ void TextureManager::Init(ref_ptr<dp::GraphicsContext> context, Params const & p
|
|||
|
||||
m_maxTextureSize = std::min(kMaxTextureSize, dp::SupportManager::Instance().GetMaxTextureSize());
|
||||
auto const apiVersion = context->GetApiVersion();
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
GLFunctions::glPixelStore(gl_const::GLUnpackAlignment, 1);
|
||||
|
||||
// Initialize symbols.
|
||||
|
@ -323,16 +323,13 @@ void TextureManager::Init(ref_ptr<dp::GraphicsContext> context, Params const & p
|
|||
CreateArrowTexture(context, make_ref(m_textureAllocator), params.m_arrowTexturePath,
|
||||
params.m_arrowTextureUseDefaultResourceFolder);
|
||||
|
||||
// SMAA is not supported on OpenGL ES2.
|
||||
if (apiVersion != dp::ApiVersion::OpenGLES2)
|
||||
{
|
||||
m_smaaAreaTexture =
|
||||
make_unique_dp<StaticTexture>(context, "smaa-area.png", StaticTexture::kDefaultResource,
|
||||
dp::TextureFormat::RedGreen, make_ref(m_textureAllocator));
|
||||
m_smaaSearchTexture =
|
||||
make_unique_dp<StaticTexture>(context, "smaa-search.png", StaticTexture::kDefaultResource,
|
||||
dp::TextureFormat::Alpha, make_ref(m_textureAllocator));
|
||||
}
|
||||
// SMAA.
|
||||
m_smaaAreaTexture =
|
||||
make_unique_dp<StaticTexture>(context, "smaa-area.png", StaticTexture::kDefaultResource,
|
||||
dp::TextureFormat::RedGreen, make_ref(m_textureAllocator));
|
||||
m_smaaSearchTexture =
|
||||
make_unique_dp<StaticTexture>(context, "smaa-search.png", StaticTexture::kDefaultResource,
|
||||
dp::TextureFormat::Red, make_ref(m_textureAllocator));
|
||||
|
||||
// Initialize patterns (reserved ./data/patterns.txt lines count).
|
||||
std::set<PenPatternT> patterns;
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace dp
|
|||
enum class TextureFormat : uint8_t
|
||||
{
|
||||
RGBA8,
|
||||
Alpha,
|
||||
Red,
|
||||
RedGreen,
|
||||
DepthStencil,
|
||||
Depth,
|
||||
|
@ -21,7 +21,7 @@ inline std::string DebugPrint(TextureFormat tf)
|
|||
switch (tf)
|
||||
{
|
||||
case TextureFormat::RGBA8: return "RGBA8";
|
||||
case TextureFormat::Alpha: return "Alpha";
|
||||
case TextureFormat::Red: return "Red";
|
||||
case TextureFormat::RedGreen: return "RedGreen";
|
||||
case TextureFormat::DepthStencil: return "DepthStencil";
|
||||
case TextureFormat::Depth: return "Depth";
|
||||
|
@ -50,7 +50,7 @@ inline uint8_t GetBytesPerPixel(TextureFormat format)
|
|||
switch (format)
|
||||
{
|
||||
case TextureFormat::RGBA8: result = 4; break;
|
||||
case TextureFormat::Alpha: result = 1; break;
|
||||
case TextureFormat::Red: result = 1; break;
|
||||
case TextureFormat::RedGreen: result = 2; break;
|
||||
case TextureFormat::DepthStencil: result = 4; break;
|
||||
case TextureFormat::Depth: result = 4; break;
|
||||
|
|
|
@ -56,9 +56,6 @@ public:
|
|||
return false;
|
||||
|
||||
m_program = program;
|
||||
// If OES_vertex_array_object not supported, than buffers will be bound on each render call.
|
||||
if (!GLFunctions::ExtensionsList.IsSupported(GLExtensionsList::VertexArrayObject))
|
||||
return false;
|
||||
|
||||
if (m_VAO != 0)
|
||||
GLFunctions::glDeleteVertexArray(m_VAO);
|
||||
|
@ -68,19 +65,14 @@ public:
|
|||
|
||||
bool Bind() override
|
||||
{
|
||||
if (GLFunctions::ExtensionsList.IsSupported(GLExtensionsList::VertexArrayObject))
|
||||
{
|
||||
ASSERT(m_VAO != 0, ("You need to call Build method before bind it and render."));
|
||||
GLFunctions::glBindVertexArray(m_VAO);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
ASSERT(m_VAO != 0, ("You need to call Build method before bind it and render."));
|
||||
GLFunctions::glBindVertexArray(m_VAO);
|
||||
return true;
|
||||
}
|
||||
|
||||
void Unbind() override
|
||||
{
|
||||
if (GLFunctions::ExtensionsList.IsSupported(GLExtensionsList::VertexArrayObject))
|
||||
GLFunctions::glBindVertexArray(0);
|
||||
GLFunctions::glBindVertexArray(0);
|
||||
}
|
||||
|
||||
void BindBuffers(BuffersMap const & buffers) const override
|
||||
|
@ -126,10 +118,6 @@ VertexArrayBuffer::VertexArrayBuffer(uint32_t indexBufferSize, uint32_t dataBuff
|
|||
, m_batcherHash(batcherHash)
|
||||
{
|
||||
m_indexBuffer = make_unique_dp<IndexBuffer>(indexBufferSize);
|
||||
|
||||
// Adreno 200 GPUs aren't able to share OpenGL resources between 2 OGL-contexts correctly,
|
||||
// so we have to create and destroy VBO on one context.
|
||||
m_moveToGpuOnBuild = SupportManager::Instance().IsAdreno200Device();
|
||||
}
|
||||
|
||||
VertexArrayBuffer::~VertexArrayBuffer()
|
||||
|
@ -142,8 +130,7 @@ VertexArrayBuffer::~VertexArrayBuffer()
|
|||
|
||||
void VertexArrayBuffer::Preflush(ref_ptr<GraphicsContext> context)
|
||||
{
|
||||
if (!m_moveToGpuOnBuild)
|
||||
PreflushImpl(context);
|
||||
PreflushImpl(context);
|
||||
}
|
||||
|
||||
void VertexArrayBuffer::PreflushImpl(ref_ptr<GraphicsContext> context)
|
||||
|
@ -163,7 +150,7 @@ void VertexArrayBuffer::PreflushImpl(ref_ptr<GraphicsContext> context)
|
|||
// Preflush can be called on BR, where impl is not initialized.
|
||||
// For Metal rendering this code has no meaning.
|
||||
auto const apiVersion = context->GetApiVersion();
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
GLFunctions::glBindBuffer(0, gl_const::GLElementArrayBuffer);
|
||||
GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer);
|
||||
|
@ -199,7 +186,7 @@ void VertexArrayBuffer::RenderRange(ref_ptr<GraphicsContext> context,
|
|||
|
||||
void VertexArrayBuffer::Build(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgram> program)
|
||||
{
|
||||
if (m_moveToGpuOnBuild && !m_isPreflushed)
|
||||
if (!m_isPreflushed)
|
||||
PreflushImpl(context);
|
||||
|
||||
if (!HasBuffers())
|
||||
|
@ -208,7 +195,7 @@ void VertexArrayBuffer::Build(ref_ptr<GraphicsContext> context, ref_ptr<GpuProgr
|
|||
if (!m_impl)
|
||||
{
|
||||
auto const apiVersion = context->GetApiVersion();
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
m_impl = make_unique_dp<GLVertexArrayBufferImpl>();
|
||||
}
|
||||
|
|
|
@ -124,7 +124,6 @@ private:
|
|||
drape_ptr<IndexBuffer> m_indexBuffer;
|
||||
|
||||
bool m_isPreflushed = false;
|
||||
bool m_moveToGpuOnBuild = false;
|
||||
bool m_isChanged = false;
|
||||
BindingInfoArray m_bindingInfo;
|
||||
uint8_t m_bindingInfoCount = 0;
|
||||
|
|
|
@ -158,7 +158,7 @@ VkFormat VulkanFormatUnpacker::Unpack(TextureFormat format)
|
|||
switch (format)
|
||||
{
|
||||
case TextureFormat::RGBA8: return VK_FORMAT_R8G8B8A8_UNORM;
|
||||
case TextureFormat::Alpha: return VK_FORMAT_R8_UNORM;
|
||||
case TextureFormat::Red: return VK_FORMAT_R8_UNORM;
|
||||
case TextureFormat::RedGreen: return VK_FORMAT_R8G8_UNORM;
|
||||
#if defined(OMIM_OS_MAC)
|
||||
case TextureFormat::DepthStencil: return VK_FORMAT_D32_SFLOAT_S8_UINT;
|
||||
|
|
|
@ -308,7 +308,7 @@ Arrow3d::Arrow3d(ref_ptr<dp::GraphicsContext> context, ref_ptr<dp::TextureManage
|
|||
|
||||
// Workaround for OpenGL: some devices require any texture to be set in the rendering pipeline.
|
||||
auto const apiVersion = context->GetApiVersion();
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES2 || apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
m_state.SetColorTexture(texMng->GetSymbolsTexture());
|
||||
|
||||
m_isValid = preloadedData.m_meshData.has_value();
|
||||
|
|
|
@ -1426,7 +1426,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView, bool activeFram
|
|||
RefreshBgColor();
|
||||
|
||||
uint32_t clearBits = dp::ClearBits::ColorBit | dp::ClearBits::DepthBit;
|
||||
if (m_apiVersion == dp::ApiVersion::OpenGLES2 || m_apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (m_apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
clearBits |= dp::ClearBits::StencilBit;
|
||||
|
||||
uint32_t storeBits = dp::ClearBits::ColorBit;
|
||||
|
@ -1524,7 +1524,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView, bool activeFram
|
|||
if (IsValidCurrentZoom())
|
||||
{
|
||||
uint32_t clearBits = dp::ClearBits::DepthBit;
|
||||
if (m_apiVersion == dp::ApiVersion::OpenGLES2 || m_apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (m_apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
clearBits |= dp::ClearBits::StencilBit;
|
||||
m_context->Clear(clearBits, dp::kClearBitsStoreAll);
|
||||
|
||||
|
|
|
@ -369,7 +369,6 @@ void LayerCacher::CacheScaleFpsLabel(ref_ptr<dp::GraphicsContext> context, Posit
|
|||
std::string apiLabel;
|
||||
switch (apiVersion)
|
||||
{
|
||||
case dp::ApiVersion::OpenGLES2: apiLabel = "GL2"; break;
|
||||
case dp::ApiVersion::OpenGLES3: apiLabel = "GL3"; break;
|
||||
case dp::ApiVersion::Metal: apiLabel = "M"; break;
|
||||
case dp::ApiVersion::Vulkan: apiLabel = "V"; break;
|
||||
|
|
|
@ -203,10 +203,6 @@ bool PostprocessRenderer::IsEnabled() const
|
|||
void PostprocessRenderer::SetEffectEnabled(ref_ptr<dp::GraphicsContext> context,
|
||||
Effect effect, bool enabled)
|
||||
{
|
||||
// Do not support AA for OpenGLES 2.0.
|
||||
if (m_apiVersion == dp::ApiVersion::OpenGLES2 && effect == Effect::Antialiasing)
|
||||
return;
|
||||
|
||||
auto const oldValue = m_effects;
|
||||
auto const effectMask = static_cast<uint32_t>(effect);
|
||||
m_effects = (m_effects & ~effectMask) | (enabled ? effectMask : 0);
|
||||
|
@ -238,7 +234,7 @@ bool PostprocessRenderer::CanRenderAntialiasing() const
|
|||
return false;
|
||||
}
|
||||
|
||||
if (m_apiVersion == dp::ApiVersion::OpenGLES2 || m_apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (m_apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
return m_staticTextures->m_smaaAreaTexture->GetID() != 0 &&
|
||||
m_staticTextures->m_smaaSearchTexture->GetID() != 0;
|
||||
|
@ -289,7 +285,7 @@ bool PostprocessRenderer::EndFrame(ref_ptr<dp::GraphicsContext> context,
|
|||
ASSERT(m_staticTextures->m_smaaAreaTexture != nullptr, ());
|
||||
ASSERT(m_staticTextures->m_smaaSearchTexture != nullptr, ());
|
||||
|
||||
if (m_apiVersion == dp::ApiVersion::OpenGLES2 || m_apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
if (m_apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
{
|
||||
ASSERT_GREATER(m_staticTextures->m_smaaAreaTexture->GetID(), 0, ());
|
||||
ASSERT_GREATER(m_staticTextures->m_smaaSearchTexture->GetID(), 0, ());
|
||||
|
@ -418,15 +414,12 @@ void PostprocessRenderer::UpdateFramebuffers(ref_ptr<dp::GraphicsContext> contex
|
|||
ASSERT_NOT_EQUAL(height, 0, ());
|
||||
|
||||
CHECK_EQUAL(m_apiVersion, context->GetApiVersion(), ());
|
||||
InitFramebuffer(context, m_mainFramebuffer, width, height, true /* depthEnabled */,
|
||||
m_apiVersion != dp::ApiVersion::OpenGLES2 /* stencilEnabled */);
|
||||
InitFramebuffer(context, m_mainFramebuffer, width, height, true /* depthEnabled */, true /* stencilEnabled */);
|
||||
m_isMainFramebufferRendered = false;
|
||||
|
||||
m_isSmaaFramebufferRendered = false;
|
||||
if (!m_isRouteFollowingActive && IsEffectEnabled(Effect::Antialiasing))
|
||||
{
|
||||
CHECK_NOT_EQUAL(m_apiVersion, dp::ApiVersion::OpenGLES2, ());
|
||||
|
||||
InitFramebuffer(context, m_edgesFramebuffer, dp::TextureFormat::RedGreen,
|
||||
m_mainFramebuffer->GetDepthStencilRef(),
|
||||
width, height);
|
||||
|
|
|
@ -81,7 +81,7 @@ double getExactDPI(double contentScaleFactor)
|
|||
if (tempContext != nil)
|
||||
apiVersion = dp::ApiVersion::OpenGLES3;
|
||||
else
|
||||
apiVersion = dp::ApiVersion::OpenGLES2;
|
||||
CHECK(false, ("OpenGL ES3 is not supported"));
|
||||
}
|
||||
|
||||
return apiVersion;
|
||||
|
|
|
@ -17,20 +17,14 @@ iosOGLContext::iosOGLContext(CAEAGLLayer * layer, dp::ApiVersion apiVersion,
|
|||
, m_frameBufferId(0)
|
||||
, m_presentAvailable(true)
|
||||
{
|
||||
EAGLRenderingAPI api;
|
||||
if (m_apiVersion == dp::ApiVersion::OpenGLES3)
|
||||
api = kEAGLRenderingAPIOpenGLES3;
|
||||
else
|
||||
api = kEAGLRenderingAPIOpenGLES2;
|
||||
|
||||
if (contextToShareWith != NULL)
|
||||
{
|
||||
m_nativeContext = [[EAGLContext alloc] initWithAPI:api
|
||||
m_nativeContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3
|
||||
sharegroup: contextToShareWith->m_nativeContext.sharegroup];
|
||||
}
|
||||
else
|
||||
{
|
||||
m_nativeContext = [[EAGLContext alloc] initWithAPI:api];
|
||||
m_nativeContext = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES3];
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -395,7 +395,7 @@ private:
|
|||
public:
|
||||
struct DrapeCreationParams
|
||||
{
|
||||
dp::ApiVersion m_apiVersion = dp::ApiVersion::OpenGLES2;
|
||||
dp::ApiVersion m_apiVersion = dp::ApiVersion::OpenGLES3;
|
||||
float m_visualScale = 1.0f;
|
||||
int m_surfaceWidth = 0;
|
||||
int m_surfaceHeight = 0;
|
||||
|
|
|
@ -107,7 +107,7 @@ void MapWidget::CreateEngine()
|
|||
{
|
||||
Framework::DrapeCreationParams p;
|
||||
|
||||
p.m_apiVersion = m_apiOpenGLES3 ? dp::ApiVersion::OpenGLES3 : dp::ApiVersion::OpenGLES2;
|
||||
p.m_apiVersion = dp::ApiVersion::OpenGLES3;
|
||||
|
||||
p.m_surfaceWidth = m_screenshotMode ? width() : static_cast<int>(m_ratio * width());
|
||||
p.m_surfaceHeight = m_screenshotMode ? height() : static_cast<int>(m_ratio * height());
|
||||
|
@ -232,8 +232,6 @@ void MapWidget::Build()
|
|||
{
|
||||
std::string_view vertexSrc;
|
||||
std::string_view fragmentSrc;
|
||||
if (m_apiOpenGLES3)
|
||||
{
|
||||
#if defined(OMIM_OS_LINUX)
|
||||
vertexSrc = ":common/shaders/gles_300.vsh.glsl";
|
||||
fragmentSrc = ":common/shaders/gles_300.fsh.glsl";
|
||||
|
@ -241,12 +239,6 @@ void MapWidget::Build()
|
|||
vertexSrc = ":common/shaders/gl_150.vsh.glsl";
|
||||
fragmentSrc = ":common/shaders/gl_150.fsh.glsl";
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
vertexSrc = ":common/shaders/gles_200.vsh.glsl";
|
||||
fragmentSrc = ":common/shaders/gles_200.fsh.glsl";
|
||||
}
|
||||
|
||||
m_program = std::make_unique<QOpenGLShaderProgram>(this);
|
||||
m_program->addShaderFromSourceFile(QOpenGLShader::Vertex, vertexSrc.data());
|
||||
|
@ -348,8 +340,6 @@ void MapWidget::initializeGL()
|
|||
if (!m_screenshotMode)
|
||||
m_ratio = devicePixelRatio();
|
||||
|
||||
m_apiOpenGLES3 = true;
|
||||
|
||||
#if defined(OMIM_OS_LINUX)
|
||||
{
|
||||
QOpenGLFunctions * funcs = context()->functions();
|
||||
|
@ -367,29 +357,14 @@ void MapWidget::initializeGL()
|
|||
auto fmt = context()->format();
|
||||
if (context()->format().version() < qMakePair(3, 0))
|
||||
{
|
||||
LOG(LINFO, ("OpenGL ES version is below 3.0, taking the OpenGL ES 2.0 path"));
|
||||
m_apiOpenGLES3 = false;
|
||||
|
||||
constexpr const char* requiredExtensions[3] =
|
||||
{ "GL_EXT_map_buffer_range", "GL_OES_mapbuffer", "GL_OES_vertex_array_object" };
|
||||
for (auto & requiredExtension : requiredExtensions)
|
||||
{
|
||||
if (context()->hasExtension(QByteArray::fromStdString(requiredExtension)))
|
||||
LOG(LDEBUG, ("Found OpenGL ES 2.0 extension: ", requiredExtension));
|
||||
else
|
||||
LOG(LCRITICAL, ("A required OpenGL ES 2.0 extension is missing:", requiredExtension));
|
||||
}
|
||||
fmt.setProfile(QSurfaceFormat::CompatibilityProfile);
|
||||
fmt.setVersion(2, 0);
|
||||
CHECK(false, ("OpenGL ES2 is not supported"));
|
||||
}
|
||||
else
|
||||
{
|
||||
LOG(LINFO, ("OpenGL version is at least 3.0, enabling GLSL '#version 300 es'"));
|
||||
m_apiOpenGLES3 = true;
|
||||
fmt.setVersion(3, 0);
|
||||
}
|
||||
|
||||
|
||||
QSurfaceFormat::setDefaultFormat(fmt);
|
||||
}
|
||||
#endif
|
||||
|
|
|
@ -97,7 +97,6 @@ protected:
|
|||
void wheelEvent(QWheelEvent * e) override;
|
||||
|
||||
Framework & m_framework;
|
||||
bool m_apiOpenGLES3;
|
||||
bool m_screenshotMode;
|
||||
ScaleSlider * m_slider;
|
||||
SliderState m_sliderState;
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
<file>spinner12.png</file>
|
||||
<file>shaders/gl_150.fsh.glsl</file>
|
||||
<file>shaders/gl_150.vsh.glsl</file>
|
||||
<file>shaders/gles_200.fsh.glsl</file>
|
||||
<file>shaders/gles_200.vsh.glsl</file>
|
||||
<file>shaders/gles_300.fsh.glsl</file>
|
||||
<file>shaders/gles_300.vsh.glsl</file>
|
||||
</qresource>
|
||||
|
|
|
@ -1,15 +0,0 @@
|
|||
#ifdef GL_ES
|
||||
#ifdef GL_FRAGMENT_PRECISION_HIGH
|
||||
precision highp float;
|
||||
#else
|
||||
precision mediump float;
|
||||
#endif
|
||||
#endif
|
||||
|
||||
uniform sampler2D u_sampler;
|
||||
varying vec2 v_texCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = vec4(texture2D(u_sampler, v_texCoord).rgb, 1.0);
|
||||
}
|
|
@ -1,9 +0,0 @@
|
|||
attribute vec4 a_position;
|
||||
uniform vec2 u_samplerSize;
|
||||
varying vec2 v_texCoord;
|
||||
|
||||
void main()
|
||||
{
|
||||
v_texCoord = vec2(a_position.z * u_samplerSize.x, a_position.w * u_samplerSize.y);
|
||||
gl_Position = vec4(a_position.x, a_position.y, 0.0, 1.0);
|
||||
}
|
|
@ -51,8 +51,7 @@ void RunTestLoop(char const * testName, testing::RenderFunction && fn, bool auto
|
|||
app.exec();
|
||||
}
|
||||
|
||||
void RunTestInOpenGLOffscreenEnvironment(char const * testName, bool apiOpenGLES3,
|
||||
testing::TestFunction const & fn)
|
||||
void RunTestInOpenGLOffscreenEnvironment(char const * testName, testing::TestFunction const & fn)
|
||||
{
|
||||
std::vector<char> buf(strlen(testName) + 1);
|
||||
strcpy(buf.data(), testName);
|
||||
|
@ -71,16 +70,8 @@ void RunTestInOpenGLOffscreenEnvironment(char const * testName, bool apiOpenGLES
|
|||
fmt.setSwapBehavior(QSurfaceFormat::DoubleBuffer);
|
||||
fmt.setSwapInterval(1);
|
||||
fmt.setDepthBufferSize(16);
|
||||
if (apiOpenGLES3)
|
||||
{
|
||||
fmt.setProfile(QSurfaceFormat::CoreProfile);
|
||||
fmt.setVersion(3, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
fmt.setProfile(QSurfaceFormat::CompatibilityProfile);
|
||||
fmt.setVersion(2, 1);
|
||||
}
|
||||
fmt.setProfile(QSurfaceFormat::CoreProfile);
|
||||
fmt.setVersion(3, 2);
|
||||
|
||||
auto surface = std::make_unique<QOffscreenSurface>();
|
||||
surface->setFormat(fmt);
|
||||
|
@ -92,7 +83,7 @@ void RunTestInOpenGLOffscreenEnvironment(char const * testName, bool apiOpenGLES
|
|||
context->makeCurrent(surface.get());
|
||||
|
||||
if (fn)
|
||||
fn(apiOpenGLES3);
|
||||
fn();
|
||||
|
||||
context->doneCurrent();
|
||||
surface->destroy();
|
||||
|
|
|
@ -6,9 +6,9 @@ class QPaintDevice;
|
|||
namespace testing
|
||||
{
|
||||
using RenderFunction = std::function<void (QPaintDevice *)>;
|
||||
using TestFunction = std::function<void (bool apiOpenGLES3)>;
|
||||
using TestFunction = std::function<void ()>;
|
||||
} // namespace testing
|
||||
|
||||
extern void RunTestLoop(char const * testName, testing::RenderFunction && fn, bool autoExit = true);
|
||||
|
||||
extern void RunTestInOpenGLOffscreenEnvironment(char const * testName, bool apiOpenGLES3, testing::TestFunction const & fn);
|
||||
extern void RunTestInOpenGLOffscreenEnvironment(char const * testName, testing::TestFunction const & fn);
|
||||
|
|
|
@ -1,15 +1,26 @@
|
|||
attribute vec3 a_position;
|
||||
attribute vec2 a_colorTexCoords;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
layout (location = 0) in vec3 a_position;
|
||||
layout (location = 1) in vec2 a_colorTexCoords;
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
uniform sampler2D u_colorTex;
|
||||
varying LOW_P vec4 v_color;
|
||||
layout (location = 0) out LOW_P vec4 v_color;
|
||||
#else
|
||||
varying vec2 v_colorTexCoords;
|
||||
layout (location = 1) out vec2 v_colorTexCoords;
|
||||
#endif
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
layout (binding = 1) uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
|
@ -17,7 +28,7 @@ void main()
|
|||
vec4 pos = vec4(a_position, 1) * u_modelView * u_projection;
|
||||
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
|
||||
![]() I’m not sure I understood what reflection you meant. The reflection wasn’t changed as far as I see. This code is GLES3 shader syntax that can be directly consumed by Vulkan (or in GLES3 code with uniform buffers support). I’m not sure I understood what reflection you meant. The reflection wasn’t changed as far as I see. This code is GLES3 shader syntax that can be directly consumed by Vulkan (or in GLES3 code with uniform buffers support).
I didn’t notice that any rendering logic was dramatically changed, it looks safe for me.
cc @renderexpert
![]() @AndrewShkrob Nothing really changed in terms of reflection. You can find uniform in the old syntax that I removed above: organicmaps/organicmaps#10256/files So what I did here, I removed old syntax and used modern one for all shaders. It makes these shaders close to Metal ones, so it simplifies synchronous cross-language changes of shaders. @AndrewShkrob Nothing really changed in terms of reflection. You can find uniform in the old syntax that I removed above:
https://git.omaps.dev/organicmaps/organicmaps/pulls/10256/files#diff-4ad123dd71cdb25bc87eab7d6c71fb11dfb2a9a602afa5de2de9971c386e55d3L1-L7
So what I did here, I removed old syntax and used modern one for all shaders. It makes these shaders close to Metal ones, so it simplifies synchronous cross-language changes of shaders.
|
||||
#ifdef ENABLE_VTF
|
||||
v_color = texture2D(u_colorTex, a_colorTexCoords);
|
||||
v_color = texture(u_colorTex, a_colorTexCoords);
|
||||
#else
|
||||
v_colorTexCoords = a_colorTexCoords;
|
||||
#endif
|
||||
|
|
|
@ -1,34 +1,36 @@
|
|||
attribute vec3 a_position;
|
||||
attribute vec3 a_normal;
|
||||
attribute vec2 a_colorTexCoords;
|
||||
layout (location = 0) in vec3 a_position;
|
||||
layout (location = 1) in vec3 a_normal;
|
||||
layout (location = 2) in vec2 a_colorTexCoords;
|
||||
layout (location = 0) out vec2 v_colorTexCoords;
|
||||
layout (location = 1) out float v_intensity;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
uniform float u_zScale;
|
||||
|
||||
varying vec2 v_colorTexCoords;
|
||||
varying float v_intensity;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
const vec4 kNormalizedLightDir = vec4(0.3162, 0.0, 0.9486, 0.0);
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pos = vec4(a_position, 1.0) * u_modelView;
|
||||
|
||||
vec4 normal = vec4(a_position + a_normal, 1.0) * u_modelView;
|
||||
normal.xyw = (normal * u_projection).xyw;
|
||||
normal.z = normal.z * u_zScale;
|
||||
|
||||
pos.xyw = (pos * u_projection).xyw;
|
||||
pos.z = a_position.z * u_zScale;
|
||||
|
||||
vec4 normDir = normal - pos;
|
||||
if (dot(normDir, normDir) != 0.0)
|
||||
v_intensity = max(0.0, -dot(kNormalizedLightDir, normalize(normDir)));
|
||||
else
|
||||
v_intensity = 0.0;
|
||||
|
||||
gl_Position = u_pivotTransform * pos;
|
||||
#ifdef VULKAN
|
||||
gl_Position.y = -gl_Position.y;
|
||||
|
|
|
@ -1,16 +1,26 @@
|
|||
attribute vec3 a_position;
|
||||
attribute vec2 a_colorTexCoords;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
uniform float u_zScale;
|
||||
layout (location = 0) in vec3 a_position;
|
||||
layout (location = 1) in vec2 a_colorTexCoords;
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
uniform sampler2D u_colorTex;
|
||||
varying LOW_P vec4 v_color;
|
||||
layout (location = 0) out LOW_P vec4 v_color;
|
||||
#else
|
||||
varying vec2 v_colorTexCoords;
|
||||
layout (location = 1) out vec2 v_colorTexCoords;
|
||||
#endif
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
layout (binding = 1) uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
|
@ -23,9 +33,8 @@ void main()
|
|||
gl_Position.y = -gl_Position.y;
|
||||
gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;
|
||||
#endif
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
v_color = texture2D(u_colorTex, a_colorTexCoords);
|
||||
v_color = texture(u_colorTex, a_colorTexCoords);
|
||||
#else
|
||||
v_colorTexCoords = a_colorTexCoords;
|
||||
#endif
|
||||
|
|
|
@ -1,16 +1,19 @@
|
|||
varying vec3 v_normal;
|
||||
layout (location = 0) in vec3 v_normal;
|
||||
|
||||
#ifdef SAMSUNG_GOOGLE_NEXUS
|
||||
uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
layout (location = 0) out vec4 v_FragColor;
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_transform;
|
||||
mat4 u_normalTransform;
|
||||
vec4 u_color;
|
||||
vec2 u_texCoordFlipping;
|
||||
};
|
||||
|
||||
const vec3 lightDir = vec3(0.316, 0.0, 0.948);
|
||||
|
||||
uniform vec4 u_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
float phongDiffuse = max(0.0, -dot(lightDir, v_normal));
|
||||
vec4 resColor = vec4((phongDiffuse * 0.5 + 0.5) * u_color.rgb, u_color.a);
|
||||
gl_FragColor = samsungGoogleNexusWorkaround(resColor);
|
||||
v_FragColor = vec4((phongDiffuse * 0.5 + 0.5) * u_color.rgb, u_color.a);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,15 @@
|
|||
attribute vec3 a_pos;
|
||||
attribute vec3 a_normal;
|
||||
layout (location = 0) in vec3 a_pos;
|
||||
layout (location = 1) in vec3 a_normal;
|
||||
|
||||
uniform mat4 u_transform;
|
||||
uniform mat4 u_normalTransform;
|
||||
layout (location = 0) out vec3 v_normal;
|
||||
|
||||
varying vec3 v_normal;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_transform;
|
||||
mat4 u_normalTransform;
|
||||
vec4 u_color;
|
||||
vec2 u_texCoordFlipping;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
varying float v_intensity;
|
||||
layout (location = 0) in float v_intensity;
|
||||
|
||||
#ifdef SAMSUNG_GOOGLE_NEXUS
|
||||
uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
layout (location = 0) out vec4 v_FragColor;
|
||||
|
||||
uniform vec4 u_color;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_transform;
|
||||
mat4 u_normalTransform;
|
||||
vec4 u_color;
|
||||
vec2 u_texCoordFlipping;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 resColor = vec4(u_color.rgb, u_color.a * smoothstep(0.7, 1.0, v_intensity));
|
||||
gl_FragColor = samsungGoogleNexusWorkaround(resColor);
|
||||
v_FragColor = vec4(u_color.rgb, u_color.a * smoothstep(0.7, 1.0, v_intensity));
|
||||
}
|
||||
|
|
|
@ -1,13 +1,16 @@
|
|||
varying float v_intensity;
|
||||
layout (location = 0) in float v_intensity;
|
||||
|
||||
#ifdef SAMSUNG_GOOGLE_NEXUS
|
||||
uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
layout (location = 0) out vec4 v_FragColor;
|
||||
|
||||
uniform vec4 u_color;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_transform;
|
||||
mat4 u_normalTransform;
|
||||
vec4 u_color;
|
||||
vec2 u_texCoordFlipping;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 resColor = vec4(u_color.rgb, u_color.a * v_intensity);
|
||||
gl_FragColor = samsungGoogleNexusWorkaround(resColor);
|
||||
v_FragColor = vec4(u_color.rgb, u_color.a * v_intensity);
|
||||
}
|
||||
|
|
|
@ -1,9 +1,15 @@
|
|||
attribute vec3 a_pos;
|
||||
attribute vec2 a_texCoords;
|
||||
layout (location = 0) in vec3 a_pos;
|
||||
layout (location = 1) in vec2 a_texCoords;
|
||||
|
||||
uniform mat4 u_transform;
|
||||
layout (location = 0) out float v_intensity;
|
||||
|
||||
varying float v_intensity;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_transform;
|
||||
mat4 u_normalTransform;
|
||||
vec4 u_color;
|
||||
vec2 u_texCoordFlipping;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
@ -1,15 +1,23 @@
|
|||
varying vec3 v_normal;
|
||||
varying vec2 v_texCoords;
|
||||
layout (location = 0) in vec3 v_normal;
|
||||
layout (location = 1) in vec2 v_texCoords;
|
||||
|
||||
uniform sampler2D u_colorTex;
|
||||
layout (location = 0) out vec4 v_FragColor;
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_transform;
|
||||
mat4 u_normalTransform;
|
||||
vec4 u_color;
|
||||
vec2 u_texCoordFlipping;
|
||||
};
|
||||
|
||||
layout (binding = 1) uniform sampler2D u_colorTex;
|
||||
|
||||
const vec3 lightDir = vec3(0.316, 0.0, 0.948);
|
||||
|
||||
uniform vec4 u_color;
|
||||
|
||||
void main()
|
||||
{
|
||||
float phongDiffuse = max(0.0, -dot(lightDir, v_normal));
|
||||
vec4 color = texture2D(u_colorTex, v_texCoords) * u_color;
|
||||
gl_FragColor = vec4((phongDiffuse * 0.5 + 0.5) * color.rgb, color.a);
|
||||
vec4 color = texture(u_colorTex, v_texCoords) * u_color;
|
||||
v_FragColor = vec4((phongDiffuse * 0.5 + 0.5) * color.rgb, color.a);
|
||||
}
|
||||
|
|
|
@ -1,13 +1,17 @@
|
|||
attribute vec3 a_pos;
|
||||
attribute vec3 a_normal;
|
||||
attribute vec2 a_texCoords;
|
||||
layout (location = 0) in vec3 a_pos;
|
||||
layout (location = 1) in vec3 a_normal;
|
||||
layout (location = 2) in vec2 a_texCoords;
|
||||
|
||||
uniform mat4 u_transform;
|
||||
uniform mat4 u_normalTransform;
|
||||
uniform vec2 u_texCoordFlipping;
|
||||
layout (location = 0) out vec3 v_normal;
|
||||
layout (location = 1) out vec2 v_texCoords;
|
||||
|
||||
varying vec3 v_normal;
|
||||
varying vec2 v_texCoords;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_transform;
|
||||
mat4 u_normalTransform;
|
||||
vec4 u_color;
|
||||
vec2 u_texCoordFlipping;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
@ -1,12 +1,27 @@
|
|||
uniform float u_opacity;
|
||||
#ifdef ENABLE_VTF
|
||||
varying LOW_P vec4 v_color;
|
||||
layout (location = 0) in LOW_P vec4 v_color;
|
||||
#else
|
||||
uniform sampler2D u_colorTex;
|
||||
varying vec2 v_colorTexCoords;
|
||||
layout (location = 1) in vec2 v_colorTexCoords;
|
||||
#endif
|
||||
layout (location = 2) in vec3 v_radius;
|
||||
|
||||
varying vec3 v_radius;
|
||||
layout (location = 0) out vec4 v_FragColor;
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
layout (binding = 1) uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
|
||||
const float aaPixelsCount = 2.5;
|
||||
|
||||
|
@ -15,12 +30,11 @@ void main()
|
|||
#ifdef ENABLE_VTF
|
||||
LOW_P vec4 finalColor = v_color;
|
||||
#else
|
||||
LOW_P vec4 finalColor = texture2D(u_colorTex, v_colorTexCoords);
|
||||
LOW_P vec4 finalColor = texture(u_colorTex, v_colorTexCoords);
|
||||
#endif
|
||||
|
||||
float smallRadius = v_radius.z - aaPixelsCount;
|
||||
float stepValue = smoothstep(smallRadius * smallRadius, v_radius.z * v_radius.z,
|
||||
v_radius.x * v_radius.x + v_radius.y * v_radius.y);
|
||||
finalColor.a = finalColor.a * u_opacity * (1.0 - stepValue);
|
||||
gl_FragColor = finalColor;
|
||||
v_FragColor = finalColor;
|
||||
}
|
||||
|
|
|
@ -1,19 +1,29 @@
|
|||
attribute vec3 a_position;
|
||||
attribute vec3 a_normal;
|
||||
attribute vec2 a_colorTexCoords;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
layout (location = 0) in vec3 a_position;
|
||||
layout (location = 1) in vec3 a_normal;
|
||||
layout (location = 2) in vec2 a_colorTexCoords;
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
uniform sampler2D u_colorTex;
|
||||
varying LOW_P vec4 v_color;
|
||||
layout (location = 0) out LOW_P vec4 v_color;
|
||||
#else
|
||||
varying vec2 v_colorTexCoords;
|
||||
layout (location = 1) out vec2 v_colorTexCoords;
|
||||
#endif
|
||||
layout (location = 2) out vec3 v_radius;
|
||||
|
||||
varying vec3 v_radius;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
layout (binding = 1) uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
|
@ -21,7 +31,7 @@ void main()
|
|||
vec4 pos = vec4(a_normal.xy, 0, 0) + p;
|
||||
gl_Position = applyPivotTransform(pos * u_projection, u_pivotTransform, 0.0);
|
||||
#ifdef ENABLE_VTF
|
||||
v_color = texture2D(u_colorTex, a_colorTexCoords);
|
||||
v_color = texture(u_colorTex, a_colorTexCoords);
|
||||
#else
|
||||
v_colorTexCoords = a_colorTexCoords;
|
||||
#endif
|
||||
|
|
|
@ -1,11 +1,19 @@
|
|||
#ifdef SAMSUNG_GOOGLE_NEXUS
|
||||
uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
layout (location = 0) in vec3 v_radius;
|
||||
layout (location = 1) in vec4 v_color;
|
||||
|
||||
uniform float u_opacity;
|
||||
layout (location = 0) out vec4 v_FragColor;
|
||||
|
||||
varying vec3 v_radius;
|
||||
varying vec4 v_color;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
const float kAntialiasingScalar = 0.9;
|
||||
|
||||
|
@ -13,10 +21,8 @@ void main()
|
|||
{
|
||||
float d = dot(v_radius.xy, v_radius.xy);
|
||||
vec4 finalColor = v_color;
|
||||
|
||||
float aaRadius = v_radius.z * kAntialiasingScalar;
|
||||
float stepValue = smoothstep(aaRadius * aaRadius, v_radius.z * v_radius.z, d);
|
||||
finalColor.a = finalColor.a * u_opacity * (1.0 - stepValue);
|
||||
|
||||
gl_FragColor = samsungGoogleNexusWorkaround(finalColor);
|
||||
v_FragColor = finalColor;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,21 @@
|
|||
attribute vec3 a_normal;
|
||||
attribute vec3 a_position;
|
||||
attribute vec4 a_color;
|
||||
layout (location = 0) in vec3 a_normal;
|
||||
layout (location = 1) in vec3 a_position;
|
||||
layout (location = 2) in vec4 a_color;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
layout (location = 0) out vec3 v_radius;
|
||||
layout (location = 1) out vec4 v_color;
|
||||
|
||||
varying vec3 v_radius;
|
||||
varying vec4 v_color;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
|
@ -15,7 +23,6 @@ void main()
|
|||
vec4 pos = vec4(a_position.xy, 0, 1) * u_modelView;
|
||||
vec4 shiftedPos = vec4(radius.xy, 0, 0) + pos;
|
||||
gl_Position = applyPivotTransform(shiftedPos * u_projection, u_pivotTransform, 0.0);
|
||||
|
||||
v_radius = radius;
|
||||
v_color = a_color;
|
||||
}
|
||||
|
|
|
@ -1,13 +1,25 @@
|
|||
uniform float u_opacity;
|
||||
|
||||
varying vec4 v_normal;
|
||||
layout (location = 0) in vec4 v_normal;
|
||||
#ifdef ENABLE_VTF
|
||||
varying LOW_P vec4 v_color;
|
||||
layout (location = 1) in LOW_P vec4 v_color;
|
||||
#else
|
||||
uniform sampler2D u_colorTex;
|
||||
varying vec2 v_colorTexCoords;
|
||||
layout (location = 2) in vec2 v_colorTexCoords;
|
||||
layout (binding = 1) uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
|
||||
layout (location = 0) out vec4 v_FragColor;
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
const float aaPixelsCount = 2.5;
|
||||
|
||||
void main()
|
||||
|
@ -15,18 +27,15 @@ void main()
|
|||
#ifdef ENABLE_VTF
|
||||
LOW_P vec4 color = v_color;
|
||||
#else
|
||||
LOW_P vec4 color = texture2D(u_colorTex, v_colorTexCoords);
|
||||
LOW_P vec4 color = texture(u_colorTex, v_colorTexCoords);
|
||||
#endif
|
||||
|
||||
float r1 = (v_normal.z - aaPixelsCount) * (v_normal.z - aaPixelsCount);
|
||||
float r2 = v_normal.x * v_normal.x + v_normal.y * v_normal.y;
|
||||
float r3 = v_normal.z * v_normal.z;
|
||||
float alpha = mix(step(r3, r2), smoothstep(r1, r3, r2), v_normal.w);
|
||||
|
||||
LOW_P vec4 finalColor = color;
|
||||
finalColor.a = finalColor.a * u_opacity * (1.0 - alpha);
|
||||
if (finalColor.a == 0.0)
|
||||
discard;
|
||||
|
||||
gl_FragColor = finalColor;
|
||||
v_FragColor = finalColor;
|
||||
}
|
||||
|
|
|
@ -1,17 +1,28 @@
|
|||
attribute vec3 a_position;
|
||||
attribute vec4 a_normal;
|
||||
attribute vec4 a_colorTexCoords;
|
||||
layout (location = 0) in vec3 a_position;
|
||||
layout (location = 1) in vec4 a_normal;
|
||||
layout (location = 2) in vec4 a_colorTexCoords;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
|
||||
varying vec4 v_normal;
|
||||
layout (location = 0) out vec4 v_normal;
|
||||
#ifdef ENABLE_VTF
|
||||
uniform sampler2D u_colorTex;
|
||||
varying LOW_P vec4 v_color;
|
||||
layout (location = 1) out LOW_P vec4 v_color;
|
||||
#else
|
||||
varying vec2 v_colorTexCoords;
|
||||
layout (location = 2) out vec2 v_colorTexCoords;
|
||||
#endif
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
layout (binding = 1) uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
|
@ -19,9 +30,8 @@ void main()
|
|||
vec4 p = vec4(a_position, 1) * u_modelView;
|
||||
vec4 pos = vec4(a_normal.xy + a_colorTexCoords.zw, 0, 0) + p;
|
||||
gl_Position = applyPivotTransform(pos * u_projection, u_pivotTransform, 0.0);
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
v_color = texture2D(u_colorTex, a_colorTexCoords.xy);
|
||||
v_color = texture(u_colorTex, a_colorTexCoords.xy);
|
||||
#else
|
||||
v_colorTexCoords = a_colorTexCoords.xy;
|
||||
#endif
|
||||
|
|
|
@ -1,17 +1,28 @@
|
|||
attribute vec3 a_position;
|
||||
attribute vec4 a_normal;
|
||||
attribute vec4 a_colorTexCoords;
|
||||
layout (location = 0) in vec3 a_position;
|
||||
layout (location = 1) in vec4 a_normal;
|
||||
layout (location = 2) in vec4 a_colorTexCoords;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
|
||||
varying vec4 v_normal;
|
||||
layout (location = 0) out vec4 v_normal;
|
||||
#ifdef ENABLE_VTF
|
||||
uniform sampler2D u_colorTex;
|
||||
varying LOW_P vec4 v_color;
|
||||
layout (location = 1) out LOW_P vec4 v_color;
|
||||
#else
|
||||
varying vec2 v_colorTexCoords;
|
||||
layout (location = 2) out vec2 v_colorTexCoords;
|
||||
#endif
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
layout (binding = 1) uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
|
@ -19,9 +30,8 @@ void main()
|
|||
vec4 pivot = vec4(a_position.xyz, 1.0) * u_modelView;
|
||||
vec4 offset = vec4(a_normal.xy + a_colorTexCoords.zw, 0.0, 0.0) * u_projection;
|
||||
gl_Position = applyBillboardPivotTransform(pivot * u_projection, u_pivotTransform, 0.0, offset.xy);
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
v_color = texture2D(u_colorTex, a_colorTexCoords.xy);
|
||||
v_color = texture(u_colorTex, a_colorTexCoords.xy);
|
||||
#else
|
||||
v_colorTexCoords = a_colorTexCoords.xy;
|
||||
#endif
|
||||
|
|
|
@ -1,28 +1,35 @@
|
|||
varying vec2 v_colorTexCoord;
|
||||
varying vec2 v_maskTexCoord;
|
||||
//varying vec2 v_halfLength;
|
||||
layout (location = 0) in vec2 v_colorTexCoord;
|
||||
layout (location = 1) in vec2 v_maskTexCoord;
|
||||
//layout (location = 2) in vec2 v_halfLength;
|
||||
|
||||
uniform sampler2D u_colorTex;
|
||||
uniform sampler2D u_maskTex;
|
||||
uniform float u_opacity;
|
||||
layout (location = 0) out vec4 v_FragColor;
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
layout (binding = 1) uniform sampler2D u_colorTex;
|
||||
layout (binding = 2) uniform sampler2D u_maskTex;
|
||||
|
||||
//const float aaPixelsCount = 2.5;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 color = texture2D(u_colorTex, v_colorTexCoord);
|
||||
#ifdef GLES3
|
||||
float mask = texture2D(u_maskTex, v_maskTexCoord).r;
|
||||
#else
|
||||
float mask = texture2D(u_maskTex, v_maskTexCoord).a;
|
||||
#endif
|
||||
vec4 color = texture(u_colorTex, v_colorTexCoord);
|
||||
float mask = texture(u_maskTex, v_maskTexCoord).r;
|
||||
color.a = color.a * mask * u_opacity;
|
||||
|
||||
// Disabled too agressive AA-like blurring of edges,
|
||||
// see https://github.com/organicmaps/organicmaps/issues/6583.
|
||||
//float currentW = abs(v_halfLength.x);
|
||||
//float diff = v_halfLength.y - currentW;
|
||||
//color.a *= mix(0.3, 1.0, clamp(diff / aaPixelsCount, 0.0, 1.0));
|
||||
|
||||
gl_FragColor = color;
|
||||
v_FragColor = color;
|
||||
}
|
||||
|
|
|
@ -1,15 +1,23 @@
|
|||
attribute vec3 a_position;
|
||||
attribute vec3 a_normal;
|
||||
attribute vec2 a_colorTexCoord;
|
||||
attribute vec4 a_maskTexCoord;
|
||||
layout (location = 0) in vec3 a_position;
|
||||
layout (location = 1) in vec3 a_normal;
|
||||
layout (location = 2) in vec2 a_colorTexCoord;
|
||||
layout (location = 3) in vec4 a_maskTexCoord;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
layout (location = 0) out vec2 v_colorTexCoord;
|
||||
layout (location = 1) out vec2 v_maskTexCoord;
|
||||
//layout (location = 2) out vec2 v_halfLength;
|
||||
|
||||
varying vec2 v_colorTexCoord;
|
||||
varying vec2 v_maskTexCoord;
|
||||
//varying vec2 v_halfLength;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
|
@ -21,12 +29,10 @@ void main()
|
|||
transformedAxisPos = calcLineTransformedAxisPos(transformedAxisPos, a_position.xy + normal,
|
||||
u_modelView, halfWidth);
|
||||
}
|
||||
|
||||
float uOffset = min(length(vec4(kShapeCoordScalar, 0, 0, 0) * u_modelView) * a_maskTexCoord.x, 1.0);
|
||||
v_colorTexCoord = a_colorTexCoord;
|
||||
v_maskTexCoord = vec2(a_maskTexCoord.y + uOffset * a_maskTexCoord.z, a_maskTexCoord.w);
|
||||
//v_halfLength = vec2(sign(a_normal.z) * halfWidth, abs(a_normal.z));
|
||||
vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * u_projection;
|
||||
|
||||
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,11 @@
|
|||
uniform vec4 u_color;
|
||||
layout (location = 0) out vec4 v_FragColor;
|
||||
|
||||
#ifdef SAMSUNG_GOOGLE_NEXUS
|
||||
uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
vec4 u_color;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
gl_FragColor = samsungGoogleNexusWorkaround(u_color);
|
||||
v_FragColor = u_color;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
attribute vec2 a_position;
|
||||
layout (location = 0) in vec2 a_position;
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
@ -1,24 +1,35 @@
|
|||
uniform float u_opacity;
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
varying LOW_P vec4 v_color;
|
||||
layout (location = 0) in LOW_P vec4 v_color;
|
||||
#else
|
||||
uniform sampler2D u_colorTex;
|
||||
varying vec2 v_colorTexCoords;
|
||||
layout (location = 1) in vec2 v_colorTexCoords;
|
||||
layout (binding = 1) uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
layout (location = 2) in vec2 v_maskTexCoords;
|
||||
|
||||
uniform sampler2D u_maskTex;
|
||||
varying vec2 v_maskTexCoords;
|
||||
layout (location = 0) out vec4 v_FragColor;
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
layout (binding = 2) uniform sampler2D u_maskTex;
|
||||
|
||||
void main()
|
||||
{
|
||||
#ifdef ENABLE_VTF
|
||||
LOW_P vec4 color = v_color;
|
||||
#else
|
||||
LOW_P vec4 color = texture2D(u_colorTex, v_colorTexCoords);
|
||||
LOW_P vec4 color = texture(u_colorTex, v_colorTexCoords);
|
||||
#endif
|
||||
color *= texture2D(u_maskTex, v_maskTexCoords);
|
||||
color *= texture(u_maskTex, v_maskTexCoords);
|
||||
color.a *= u_opacity;
|
||||
gl_FragColor = color;
|
||||
v_FragColor = color;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,25 +1,36 @@
|
|||
attribute vec3 a_position;
|
||||
attribute vec2 a_colorTexCoords;
|
||||
attribute vec2 a_maskTexCoords;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
layout (location = 0) in vec3 a_position;
|
||||
layout (location = 1) in vec2 a_colorTexCoords;
|
||||
layout (location = 2) in vec2 a_maskTexCoords;
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
uniform sampler2D u_colorTex;
|
||||
varying LOW_P vec4 v_color;
|
||||
layout (location = 0) out LOW_P vec4 v_color;
|
||||
#else
|
||||
varying vec2 v_colorTexCoords;
|
||||
layout (location = 1) out vec2 v_colorTexCoords;
|
||||
#endif
|
||||
layout (location = 2) out vec2 v_maskTexCoords;
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
layout (binding = 1) uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
varying vec2 v_maskTexCoords;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pos = vec4(a_position, 1) * u_modelView * u_projection;
|
||||
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
|
||||
#ifdef ENABLE_VTF
|
||||
v_color = texture2D(u_colorTex, a_colorTexCoords);
|
||||
v_color = texture(u_colorTex, a_colorTexCoords);
|
||||
#else
|
||||
v_colorTexCoords = a_colorTexCoords;
|
||||
#endif
|
||||
|
|
12
shaders/GL/imgui.fsh.glsl
Normal file
12
shaders/GL/imgui.fsh.glsl
Normal file
|
@ -0,0 +1,12 @@
|
|||
layout (location = 0) in vec2 v_texCoords;
|
||||
layout (location = 1) in vec4 v_color;
|
||||
|
||||
layout (location = 0) out vec4 v_FragColor;
|
||||
|
||||
layout (binding = 1) uniform sampler2D u_colorTex;
|
||||
|
||||
void main()
|
||||
{
|
||||
LOW_P vec4 color = texture(u_colorTex, v_texCoords);
|
||||
v_FragColor = color * v_color;
|
||||
}
|
22
shaders/GL/imgui.vsh.glsl
Normal file
22
shaders/GL/imgui.vsh.glsl
Normal file
|
@ -0,0 +1,22 @@
|
|||
layout (location = 0) in vec2 a_position;
|
||||
layout (location = 1) in vec2 a_texCoords;
|
||||
layout (location = 2) in vec4 a_color;
|
||||
|
||||
layout (location = 0) out vec2 v_texCoords;
|
||||
layout (location = 1) out vec4 v_color;
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_projection;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
v_texCoords = a_texCoords;
|
||||
v_color = a_color;
|
||||
gl_Position = vec4(a_position, 0, 1) * u_projection;
|
||||
#ifdef VULKAN
|
||||
gl_Position.y = -gl_Position.y;
|
||||
gl_Position.z = (gl_Position.z + gl_Position.w) * 0.5;
|
||||
#endif
|
||||
}
|
|
@ -1,12 +1,24 @@
|
|||
uniform float u_opacity;
|
||||
#ifdef ENABLE_VTF
|
||||
varying LOW_P vec4 v_color;
|
||||
layout (location = 0) in LOW_P vec4 v_color;
|
||||
#else
|
||||
uniform sampler2D u_colorTex;
|
||||
varying vec2 v_colorTexCoord;
|
||||
layout (location = 1) in vec2 v_colorTexCoord;
|
||||
layout (binding = 1) uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
//layout (location = 2) in vec2 v_halfLength;
|
||||
|
||||
//varying vec2 v_halfLength;
|
||||
layout (location = 0) out vec4 v_FragColor;
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
//const float aaPixelsCount = 2.5;
|
||||
|
||||
|
@ -15,15 +27,13 @@ void main()
|
|||
#ifdef ENABLE_VTF
|
||||
LOW_P vec4 color = v_color;
|
||||
#else
|
||||
LOW_P vec4 color = texture2D(u_colorTex, v_colorTexCoord);
|
||||
LOW_P vec4 color = texture(u_colorTex, v_colorTexCoord);
|
||||
#endif
|
||||
color.a *= u_opacity;
|
||||
|
||||
// Disabled too agressive AA-like blurring of edges,
|
||||
// see https://github.com/organicmaps/organicmaps/issues/6583.
|
||||
//float currentW = abs(v_halfLength.x);
|
||||
//float diff = v_halfLength.y - currentW;
|
||||
//color.a *= mix(0.3, 1.0, clamp(diff / aaPixelsCount, 0.0, 1.0));
|
||||
|
||||
gl_FragColor = color;
|
||||
v_FragColor = color;
|
||||
}
|
||||
|
|
|
@ -1,19 +1,30 @@
|
|||
attribute vec3 a_position;
|
||||
attribute vec3 a_normal;
|
||||
attribute vec2 a_colorTexCoord;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
layout (location = 0) in vec3 a_position;
|
||||
layout (location = 1) in vec3 a_normal;
|
||||
layout (location = 2) in vec2 a_colorTexCoord;
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
uniform sampler2D u_colorTex;
|
||||
varying LOW_P vec4 v_color;
|
||||
layout (location = 0) out LOW_P vec4 v_color;
|
||||
#else
|
||||
varying vec2 v_colorTexCoord;
|
||||
layout (location = 1) out vec2 v_colorTexCoord;
|
||||
#endif
|
||||
|
||||
//varying vec2 v_halfLength;
|
||||
//layout (location = 2) out vec2 v_halfLength;
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
layout (binding = 1) uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
|
||||
void main()
|
||||
{
|
||||
|
@ -25,9 +36,8 @@ void main()
|
|||
transformedAxisPos = calcLineTransformedAxisPos(transformedAxisPos, a_position.xy + normal,
|
||||
u_modelView, halfWidth);
|
||||
}
|
||||
|
||||
#ifdef ENABLE_VTF
|
||||
v_color = texture2D(u_colorTex, a_colorTexCoord);
|
||||
v_color = texture(u_colorTex, a_colorTexCoord);
|
||||
#else
|
||||
v_colorTexCoord = a_colorTexCoord;
|
||||
#endif
|
||||
|
|
|
@ -1,13 +1,26 @@
|
|||
uniform sampler2D u_colorTex;
|
||||
uniform sampler2D u_maskTex;
|
||||
uniform float u_opacity;
|
||||
layout (location = 0) in vec2 v_colorTexCoords;
|
||||
layout (location = 1) in vec2 v_maskTexCoords;
|
||||
|
||||
varying vec2 v_colorTexCoords;
|
||||
varying vec2 v_maskTexCoords;
|
||||
layout (location = 0) out vec4 v_FragColor;
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
layout (binding = 1) uniform sampler2D u_colorTex;
|
||||
layout (binding = 2) uniform sampler2D u_maskTex;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 finalColor = texture2D(u_colorTex, v_colorTexCoords) * texture2D(u_maskTex, v_maskTexCoords);
|
||||
vec4 finalColor = texture(u_colorTex, v_colorTexCoords) * texture(u_maskTex, v_maskTexCoords);
|
||||
finalColor.a *= u_opacity;
|
||||
gl_FragColor = finalColor;
|
||||
v_FragColor = finalColor;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,22 @@
|
|||
attribute vec4 a_position;
|
||||
attribute vec2 a_normal;
|
||||
attribute vec2 a_colorTexCoords;
|
||||
attribute vec2 a_maskTexCoords;
|
||||
layout (location = 0) in vec4 a_position;
|
||||
layout (location = 1) in vec2 a_normal;
|
||||
layout (location = 2) in vec2 a_colorTexCoords;
|
||||
layout (location = 3) in vec2 a_maskTexCoords;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
layout (location = 0) out vec2 v_colorTexCoords;
|
||||
layout (location = 1) out vec2 v_maskTexCoords;
|
||||
|
||||
varying vec2 v_colorTexCoords;
|
||||
varying vec2 v_maskTexCoords;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
@ -1,15 +1,22 @@
|
|||
attribute vec4 a_position;
|
||||
attribute vec2 a_normal;
|
||||
attribute vec2 a_colorTexCoords;
|
||||
attribute vec2 a_maskTexCoords;
|
||||
layout (location = 0) in vec4 a_position;
|
||||
layout (location = 1) in vec2 a_normal;
|
||||
layout (location = 2) in vec2 a_colorTexCoords;
|
||||
layout (location = 3) in vec2 a_maskTexCoords;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
uniform float u_zScale;
|
||||
layout (location = 0) out vec2 v_colorTexCoords;
|
||||
layout (location = 1) out vec2 v_maskTexCoords;
|
||||
|
||||
varying vec2 v_colorTexCoords;
|
||||
varying vec2 v_maskTexCoords;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
|
|
|
@ -1,30 +1,33 @@
|
|||
attribute vec2 a_normal;
|
||||
attribute vec2 a_colorTexCoords;
|
||||
layout (location = 0) in vec2 a_normal;
|
||||
layout (location = 1) in vec2 a_colorTexCoords;
|
||||
|
||||
uniform vec3 u_position;
|
||||
uniform float u_azimut;
|
||||
layout (location = 0) out vec2 v_colorTexCoords;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
|
||||
varying vec2 v_colorTexCoords;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec4 u_position;
|
||||
vec2 u_lineParams;
|
||||
float u_accuracy;
|
||||
float u_zScale;
|
||||
float u_opacity;
|
||||
float u_azimut;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
float sinV = sin(u_azimut);
|
||||
float cosV = cos(u_azimut);
|
||||
|
||||
mat4 rotation;
|
||||
rotation[0] = vec4(cosV, sinV, 0.0, 0.0);
|
||||
rotation[1] = vec4(-sinV, cosV, 0.0, 0.0);
|
||||
rotation[2] = vec4(0.0, 0.0, 1.0, 0.0);
|
||||
rotation[3] = vec4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
vec4 pos = vec4(u_position, 1.0) * u_modelView;
|
||||
vec4 pos = vec4(u_position.xyz, 1.0) * u_modelView;
|
||||
vec4 normal = vec4(a_normal, 0, 0);
|
||||
vec4 shiftedPos = normal * rotation + pos;
|
||||
|
||||
gl_Position = applyPivotTransform(shiftedPos * u_projection, u_pivotTransform, 0.0);
|
||||
v_colorTexCoords = a_colorTexCoords;
|
||||
}
|
||||
|
|
|
@ -1,23 +1,29 @@
|
|||
attribute vec4 a_position;
|
||||
attribute vec2 a_normal;
|
||||
attribute vec2 a_colorTexCoords;
|
||||
layout (location = 0) in vec4 a_position;
|
||||
layout (location = 1) in vec2 a_normal;
|
||||
layout (location = 2) in vec2 a_colorTexCoords;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
layout (location = 0) out vec2 v_colorTexCoords;
|
||||
|
||||
varying vec2 v_colorTexCoords;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec2 u_contrastGamma;
|
||||
float u_opacity;
|
||||
float u_zScale;
|
||||
float u_interpolation;
|
||||
float u_isOutlinePass;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 pos = vec4(a_position.xyz, 1) * u_modelView;
|
||||
|
||||
float normalLen = length(a_normal);
|
||||
vec4 n = vec4(a_position.xy + a_normal * kShapeCoordScalar, 0.0, 0.0) * u_modelView;
|
||||
vec4 norm = vec4(0.0, 0.0, 0.0, 0.0);
|
||||
if (dot(n, n) != 0.0)
|
||||
norm = normalize(n) * normalLen;
|
||||
|
||||
vec4 shiftedPos = norm + pos;
|
||||
gl_Position = applyPivotTransform(shiftedPos * u_projection, u_pivotTransform, 0.0);
|
||||
v_colorTexCoords = a_colorTexCoords;
|
||||
|
|
|
@ -1,15 +1,20 @@
|
|||
attribute vec2 a_normal;
|
||||
attribute vec2 a_colorTexCoords;
|
||||
layout (location = 0) in vec2 a_normal;
|
||||
layout (location = 1) in vec2 a_colorTexCoords;
|
||||
|
||||
uniform vec3 u_position;
|
||||
uniform float u_accuracy;
|
||||
layout (location = 0) out vec2 v_colorTexCoords;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
uniform float u_zScale;
|
||||
|
||||
varying vec2 v_colorTexCoords;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec4 u_position;
|
||||
vec2 u_lineParams;
|
||||
float u_accuracy;
|
||||
float u_zScale;
|
||||
float u_opacity;
|
||||
float u_azimut;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
|
@ -17,6 +22,5 @@ void main()
|
|||
vec4 normal = vec4(a_normal * u_accuracy, 0.0, 0.0);
|
||||
position = (position + normal) * u_projection;
|
||||
gl_Position = applyPivotTransform(position, u_pivotTransform, u_position.z * u_zScale);
|
||||
|
||||
v_colorTexCoords = a_colorTexCoords;
|
||||
}
|
||||
|
|
|
@ -1,25 +1,30 @@
|
|||
// Warning! Beware to use this shader. "discard" command may significally reduce performance.
|
||||
// Unfortunately some CG algorithms cannot be implemented on OpenGL ES 2.0 without discarding
|
||||
// fragments from depth buffer.
|
||||
// Unfortunately some CG algorithms cannot be implemented without discarding fragments from depth buffer.
|
||||
|
||||
varying vec3 v_length;
|
||||
varying vec4 v_color;
|
||||
layout (location = 0) in vec3 v_length;
|
||||
layout (location = 1) in vec4 v_color;
|
||||
|
||||
#ifdef SAMSUNG_GOOGLE_NEXUS
|
||||
uniform sampler2D u_colorTex;
|
||||
#endif
|
||||
layout (location = 0) out vec4 v_FragColor;
|
||||
|
||||
uniform vec4 u_color;
|
||||
uniform vec4 u_outlineColor;
|
||||
uniform vec4 u_routeParams;
|
||||
uniform vec4 u_maskColor;
|
||||
|
||||
uniform vec2 u_fakeBorders;
|
||||
uniform vec4 u_fakeColor;
|
||||
uniform vec4 u_fakeOutlineColor;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec4 u_routeParams;
|
||||
vec4 u_color;
|
||||
vec4 u_maskColor;
|
||||
vec4 u_outlineColor;
|
||||
vec4 u_fakeColor;
|
||||
vec4 u_fakeOutlineColor;
|
||||
vec2 u_fakeBorders;
|
||||
vec2 u_pattern;
|
||||
vec2 u_angleCosSin;
|
||||
float u_arrowHalfWidth;
|
||||
float u_opacity;
|
||||
};
|
||||
|
||||
const float kAntialiasingThreshold = 0.92;
|
||||
|
||||
const float kOutlineThreshold1 = 0.81;
|
||||
const float kOutlineThreshold2 = 0.71;
|
||||
|
||||
|
@ -27,18 +32,16 @@ void main()
|
|||
{
|
||||
if (v_length.x < v_length.z)
|
||||
discard;
|
||||
|
||||
vec2 coefs = step(v_length.xx, u_fakeBorders);
|
||||
coefs.y = 1.0 - coefs.y;
|
||||
vec4 mainColor = mix(u_color, u_fakeColor, coefs.x);
|
||||
mainColor = mix(mainColor, u_fakeColor, coefs.y);
|
||||
vec4 mainOutlineColor = mix(u_outlineColor, u_fakeOutlineColor, coefs.x);
|
||||
mainOutlineColor = mix(mainOutlineColor, u_fakeOutlineColor, coefs.y);
|
||||
|
||||
vec4 color = mix(mix(mainColor, vec4(v_color.rgb, 1.0), v_color.a), mainColor, step(u_routeParams.w, 0.0));
|
||||
color = mix(color, mainOutlineColor, step(kOutlineThreshold1, abs(v_length.y)));
|
||||
color = mix(color, mainOutlineColor, smoothstep(kOutlineThreshold2, kOutlineThreshold1, abs(v_length.y)));
|
||||
color.a *= (1.0 - smoothstep(kAntialiasingThreshold, 1.0, abs(v_length.y)));
|
||||
color = vec4(mix(color.rgb, u_maskColor.rgb, u_maskColor.a), color.a);
|
||||
gl_FragColor = samsungGoogleNexusWorkaround(color);
|
||||
v_FragColor = color;
|
||||
}
|
||||
|
|
|
@ -1,16 +1,28 @@
|
|||
attribute vec3 a_position;
|
||||
attribute vec2 a_normal;
|
||||
attribute vec3 a_length;
|
||||
attribute vec4 a_color;
|
||||
layout (location = 0) in vec3 a_position;
|
||||
layout (location = 1) in vec2 a_normal;
|
||||
layout (location = 2) in vec3 a_length;
|
||||
layout (location = 3) in vec4 a_color;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
layout (location = 0) out vec3 v_length;
|
||||
layout (location = 1) out vec4 v_color;
|
||||
|
||||
uniform vec4 u_routeParams;
|
||||
|
||||
varying vec3 v_length;
|
||||
varying vec4 v_color;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec4 u_routeParams;
|
||||
vec4 u_color;
|
||||
vec4 u_maskColor;
|
||||
vec4 u_outlineColor;
|
||||
vec4 u_fakeColor;
|
||||
vec4 u_fakeOutlineColor;
|
||||
vec2 u_fakeBorders;
|
||||
vec2 u_pattern;
|
||||
vec2 u_angleCosSin;
|
||||
float u_arrowHalfWidth;
|
||||
float u_opacity;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
|
@ -24,7 +36,6 @@ void main()
|
|||
if (u_routeParams.y != 0.0)
|
||||
len = vec2(a_length.x + a_length.y * u_routeParams.y, a_length.z);
|
||||
}
|
||||
|
||||
v_length = vec3(len, u_routeParams.z);
|
||||
v_color = a_color;
|
||||
vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * u_projection;
|
||||
|
|
|
@ -1,19 +1,36 @@
|
|||
// Warning! Beware to use this shader. "discard" command may significally reduce performance.
|
||||
// Unfortunately some CG algorithms cannot be implemented on OpenGL ES 2.0 without discarding
|
||||
// fragments from depth buffer.
|
||||
// Unfortunately some CG algorithms cannot be implemented without discarding fragments from depth buffer.
|
||||
|
||||
uniform sampler2D u_colorTex;
|
||||
uniform float u_opacity;
|
||||
uniform vec4 u_maskColor;
|
||||
layout (location = 0) in vec2 v_colorTexCoords;
|
||||
|
||||
varying vec2 v_colorTexCoords;
|
||||
layout (location = 0) out vec4 v_FragColor;
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec4 u_routeParams;
|
||||
vec4 u_color;
|
||||
vec4 u_maskColor;
|
||||
vec4 u_outlineColor;
|
||||
vec4 u_fakeColor;
|
||||
vec4 u_fakeOutlineColor;
|
||||
vec2 u_fakeBorders;
|
||||
vec2 u_pattern;
|
||||
vec2 u_angleCosSin;
|
||||
float u_arrowHalfWidth;
|
||||
float u_opacity;
|
||||
};
|
||||
|
||||
layout (binding = 1) uniform sampler2D u_colorTex;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec4 finalColor = texture2D(u_colorTex, v_colorTexCoords);
|
||||
vec4 finalColor = texture(u_colorTex, v_colorTexCoords);
|
||||
finalColor.a *= u_opacity;
|
||||
if (finalColor.a < 0.01)
|
||||
discard;
|
||||
finalColor = vec4(mix(finalColor.rgb, u_maskColor.rgb, u_maskColor.a), finalColor.a);
|
||||
gl_FragColor = finalColor;
|
||||
v_FragColor = finalColor;
|
||||
}
|
||||
|
|
|
@ -1,14 +1,26 @@
|
|||
attribute vec4 a_position;
|
||||
attribute vec2 a_normal;
|
||||
attribute vec2 a_colorTexCoords;
|
||||
layout (location = 0) in vec4 a_position;
|
||||
layout (location = 1) in vec2 a_normal;
|
||||
layout (location = 2) in vec2 a_colorTexCoords;
|
||||
|
||||
uniform mat4 u_modelView;
|
||||
uniform mat4 u_projection;
|
||||
uniform mat4 u_pivotTransform;
|
||||
layout (location = 0) out vec2 v_colorTexCoords;
|
||||
|
||||
uniform float u_arrowHalfWidth;
|
||||
|
||||
varying vec2 v_colorTexCoords;
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 u_modelView;
|
||||
mat4 u_projection;
|
||||
mat4 u_pivotTransform;
|
||||
vec4 u_routeParams;
|
||||
vec4 u_color;
|
||||
vec4 u_maskColor;
|
||||
vec4 u_outlineColor;
|
||||
vec4 u_fakeColor;
|
||||
vec4 u_fakeOutlineColor;
|
||||
vec2 u_fakeBorders;
|
||||
vec2 u_pattern;
|
||||
vec2 u_angleCosSin;
|
||||
float u_arrowHalfWidth;
|
||||
float u_opacity;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
|
@ -19,9 +31,7 @@ void main()
|
|||
transformedAxisPos = calcLineTransformedAxisPos(transformedAxisPos, a_position.xy + norm,
|
||||
u_modelView, length(norm));
|
||||
}
|
||||
|
||||
v_colorTexCoords = a_colorTexCoords;
|
||||
|
||||
vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * u_projection;
|
||||
gl_Position = applyPivotTransform(pos, u_pivotTransform, 0.0);
|
||||
}
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Reference in a new issue
Could you explain this change, please?
Previously, these parameters were automatically added by the reflection and now we need to add them manually. Why?