From 8d9a1ee61c35221b71aa97de0df0a540f22656af Mon Sep 17 00:00:00 2001 From: "r.kuznetsov" Date: Mon, 26 Dec 2016 13:17:30 +0300 Subject: [PATCH] Fixed depth enable/disable setting up --- drape/debug_rect_renderer.cpp | 8 ---- drape/drape.pro | 1 + .../discarded_texturing_fragment_shader.fsh | 17 +++++++ drape/shaders/shader_index.txt | 2 +- drape_frontend/frontend_renderer.cpp | 46 ++++++++++--------- drape_frontend/frontend_renderer.hpp | 2 +- drape_frontend/gps_track_renderer.cpp | 2 - drape_frontend/route_renderer.cpp | 4 +- drape_frontend/route_shape.cpp | 42 +++++++++++------ drape_frontend/route_shape.hpp | 22 +++++---- drape_frontend/traffic_renderer.cpp | 1 - 11 files changed, 87 insertions(+), 60 deletions(-) create mode 100644 drape/shaders/discarded_texturing_fragment_shader.fsh diff --git a/drape/debug_rect_renderer.cpp b/drape/debug_rect_renderer.cpp index 2aa547bdb8..6ecb93a9aa 100644 --- a/drape/debug_rect_renderer.cpp +++ b/drape/debug_rect_renderer.cpp @@ -96,8 +96,6 @@ void DebugRectRenderer::DrawRect(ScreenBase const & screen, m2::RectF const & re GLFunctions::glBindBuffer(m_vertexBuffer, gl_const::GLArrayBuffer); GLFunctions::glBindVertexArray(m_VAO); - GLFunctions::glDisable(gl_const::GLDepthTest); - array vertices; vertices[0] = PixelPointToScreenSpace(screen, rect.LeftBottom()); vertices[1] = PixelPointToScreenSpace(screen, rect.LeftTop()); @@ -114,8 +112,6 @@ void DebugRectRenderer::DrawRect(ScreenBase const & screen, m2::RectF const & re GLFunctions::glDrawArrays(gl_const::GLLineStrip, 0, vertices.size()); - GLFunctions::glEnable(gl_const::GLDepthTest); - GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer); GLFunctions::glBindVertexArray(0); @@ -138,8 +134,6 @@ void DebugRectRenderer::DrawArrow(ScreenBase const & screen, OverlayTree::Displa GLFunctions::glBindBuffer(m_vertexBuffer, gl_const::GLArrayBuffer); GLFunctions::glBindVertexArray(m_VAO); - GLFunctions::glDisable(gl_const::GLDepthTest); - array vertices; m2::PointF const dir = (data.m_arrowEnd - data.m_arrowStart).Normalize(); m2::PointF const side = m2::PointF(-dir.y, dir.x); @@ -159,8 +153,6 @@ void DebugRectRenderer::DrawArrow(ScreenBase const & screen, OverlayTree::Displa GLFunctions::glDrawArrays(gl_const::GLLineStrip, 0, vertices.size()); - GLFunctions::glEnable(gl_const::GLDepthTest); - GLFunctions::glBindBuffer(0, gl_const::GLArrayBuffer); GLFunctions::glBindVertexArray(0); diff --git a/drape/drape.pro b/drape/drape.pro index 7c4dbeb6c3..d3498eef8f 100644 --- a/drape/drape.pro +++ b/drape/drape.pro @@ -26,6 +26,7 @@ OTHER_FILES += \ shaders/dashed_vertex_shader.vsh \ shaders/debug_rect_fragment_shader.fsh \ shaders/debug_rect_vertex_shader.vsh \ + shaders/discarded_texturing_fragment_shader.fsh \ shaders/line_fragment_shader.fsh \ shaders/line_vertex_shader.vsh \ shaders/masked_texturing_billboard_vertex_shader.vsh \ diff --git a/drape/shaders/discarded_texturing_fragment_shader.fsh b/drape/shaders/discarded_texturing_fragment_shader.fsh new file mode 100644 index 0000000000..ccbc2b766d --- /dev/null +++ b/drape/shaders/discarded_texturing_fragment_shader.fsh @@ -0,0 +1,17 @@ +// 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. + +uniform sampler2D u_colorTex; +uniform float u_opacity; + +varying vec2 v_colorTexCoords; + +void main(void) +{ + vec4 finalColor = texture2D(u_colorTex, v_colorTexCoords); + finalColor.a *= u_opacity; + if (finalColor.a < 0.01) + discard; + gl_FragColor = finalColor; +} diff --git a/drape/shaders/shader_index.txt b/drape/shaders/shader_index.txt index aa61633a49..2c2e29abce 100644 --- a/drape/shaders/shader_index.txt +++ b/drape/shaders/shader_index.txt @@ -18,7 +18,7 @@ MY_POSITION_PROGRAM my_position_shader.vsh texturing_fragment_shader.fsh BOOKMARK_PROGRAM user_mark.vsh texturing_fragment_shader.fsh ROUTE_PROGRAM route_vertex_shader.vsh route_fragment_shader.fsh ROUTE_DASH_PROGRAM route_vertex_shader.vsh route_dash_fragment_shader.fsh -ROUTE_ARROW_PROGRAM route_arrow_vertex_shader.vsh texturing_fragment_shader.fsh +ROUTE_ARROW_PROGRAM route_arrow_vertex_shader.vsh discarded_texturing_fragment_shader.fsh TRACK_POINT_PROGRAM trackpoint_vertex_shader.vsh trackpoint_fragment_shader.fsh DEBUG_RECT_PROGRAM debug_rect_vertex_shader.vsh debug_rect_fragment_shader.fsh TRANSPARENT_LAYER_PROGRAM transparent_layer_vertex_shader.vsh transparent_layer_fragment_shader.fsh diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 0cba341b98..58a5979c8f 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -1108,25 +1108,19 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) if (m_framebuffer->IsSupported()) { RenderTrafficAndRouteLayer(modelView); - - m_framebuffer->Enable(); - GLFunctions::glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - GLFunctions::glClear(); - Render3dLayer(modelView); - m_framebuffer->Disable(); - GLFunctions::glDisable(gl_const::GLDepthTest); - m_transparentLayer->Render(m_framebuffer->GetTextureId(), make_ref(m_gpuProgramManager)); + Render3dLayer(modelView, true /* useFramebuffer */); } else { - GLFunctions::glClearDepth(); - Render3dLayer(modelView); + Render3dLayer(modelView, false /* useFramebuffer */); RenderTrafficAndRouteLayer(modelView); } + // After this line we do not use depth buffer. + GLFunctions::glDisable(gl_const::GLDepthTest); + if (m_selectionShape != nullptr) { - GLFunctions::glDisable(gl_const::GLDepthTest); SelectionShape::ESelectedObject selectedObject = m_selectionShape->GetSelectedObject(); if (selectedObject == SelectionShape::OBJECT_MY_POSITION) { @@ -1145,7 +1139,6 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) m_gpsTrackRenderer->RenderTrack(modelView, m_currentZoomLevel, make_ref(m_gpuProgramManager), m_generalUniforms); - GLFunctions::glDisable(gl_const::GLDepthTest); if (m_selectionShape != nullptr && m_selectionShape->GetSelectedObject() == SelectionShape::OBJECT_USER_MARK) m_selectionShape->Render(modelView, m_currentZoomLevel, make_ref(m_gpuProgramManager), m_generalUniforms); @@ -1160,8 +1153,6 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) if (m_guiRenderer != nullptr) m_guiRenderer->Render(make_ref(m_gpuProgramManager), m_myPositionController->IsInRouting(), modelView); - GLFunctions::glEnable(gl_const::GLDepthTest); - #if defined(RENDER_DEBUG_RECTS) && defined(COLLECT_DISPLACEMENT_INFO) for (auto const & arrow : m_overlayTree->GetDisplacementInfo()) dp::DebugRectRenderer::Instance().DrawArrow(modelView, arrow); @@ -1183,19 +1174,33 @@ void FrontendRenderer::Render2dLayer(ScreenBase const & modelView) RenderSingleGroup(modelView, make_ref(group)); } -void FrontendRenderer::Render3dLayer(ScreenBase const & modelView) +void FrontendRenderer::Render3dLayer(ScreenBase const & modelView, bool useFramebuffer) { + if (useFramebuffer) + { + ASSERT(m_framebuffer->IsSupported(), ()); + m_framebuffer->Enable(); + GLFunctions::glClearColor(0.0f, 0.0f, 0.0f, 0.0f); + GLFunctions::glClear(); + } + + GLFunctions::glClearDepth(); GLFunctions::glEnable(gl_const::GLDepthTest); RenderLayer & layer = m_layers[RenderLayer::Geometry3dID]; layer.Sort(make_ref(m_overlayTree)); for (drape_ptr const & group : layer.m_renderGroups) RenderSingleGroup(modelView, make_ref(group)); + + if (useFramebuffer) + { + m_framebuffer->Disable(); + GLFunctions::glDisable(gl_const::GLDepthTest); + m_transparentLayer->Render(m_framebuffer->GetTextureId(), make_ref(m_gpuProgramManager)); + } } void FrontendRenderer::RenderOverlayLayer(ScreenBase const & modelView) { - GLFunctions::glClearDepth(); - GLFunctions::glEnable(gl_const::GLDepthTest); RenderLayer & overlay = m_layers[RenderLayer::OverlayID]; BuildOverlayTree(modelView); for (drape_ptr & group : overlay.m_renderGroups) @@ -1204,15 +1209,13 @@ void FrontendRenderer::RenderOverlayLayer(ScreenBase const & modelView) void FrontendRenderer::RenderTrafficAndRouteLayer(ScreenBase const & modelView) { + GLFunctions::glClearDepth(); + GLFunctions::glEnable(gl_const::GLDepthTest); if (m_trafficRenderer->HasRenderData()) { - GLFunctions::glClearDepth(); - GLFunctions::glEnable(gl_const::GLDepthTest); m_trafficRenderer->RenderTraffic(modelView, m_currentZoomLevel, 1.0f /* opacity */, make_ref(m_gpuProgramManager), m_generalUniforms); } - - GLFunctions::glDisable(gl_const::GLDepthTest); m_routeRenderer->RenderRoute(modelView, m_trafficRenderer->HasRenderData(), make_ref(m_gpuProgramManager), m_generalUniforms); } @@ -1650,7 +1653,6 @@ void FrontendRenderer::OnContextCreate() GLFunctions::AttachCache(this_thread::get_id()); GLFunctions::glPixelStore(gl_const::GLUnpackAlignment, 1); - GLFunctions::glEnable(gl_const::GLDepthTest); GLFunctions::glClearDepthValue(1.0); GLFunctions::glDepthFunc(gl_const::GLLessOrEqual); diff --git a/drape_frontend/frontend_renderer.hpp b/drape_frontend/frontend_renderer.hpp index f9e717c0c2..20d5289635 100755 --- a/drape_frontend/frontend_renderer.hpp +++ b/drape_frontend/frontend_renderer.hpp @@ -174,7 +174,7 @@ private: ////// /// Render part of scene void Render2dLayer(ScreenBase const & modelView); - void Render3dLayer(ScreenBase const & modelView); + void Render3dLayer(ScreenBase const & modelView, bool useFramebuffer); void RenderOverlayLayer(ScreenBase const & modelView); void RenderUserMarksLayer(ScreenBase const & modelView); void RenderTrafficAndRouteLayer(ScreenBase const & modelView); diff --git a/drape_frontend/gps_track_renderer.cpp b/drape_frontend/gps_track_renderer.cpp index 937a0c2dac..be3fae7272 100644 --- a/drape_frontend/gps_track_renderer.cpp +++ b/drape_frontend/gps_track_renderer.cpp @@ -294,8 +294,6 @@ void GpsTrackRenderer::RenderTrack(ScreenBase const & screen, int zoomLevel, if (m_handlesCache.empty() || m_handlesCache.front().second == 0) return; - GLFunctions::glClearDepth(); - ASSERT_LESS_OR_EQUAL(m_renderData.size(), m_handlesCache.size(), ()); // Render points. diff --git a/drape_frontend/route_renderer.cpp b/drape_frontend/route_renderer.cpp index 5b61e2bd6e..065b6e1f53 100644 --- a/drape_frontend/route_renderer.cpp +++ b/drape_frontend/route_renderer.cpp @@ -169,8 +169,8 @@ void RouteRenderer::UpdateRoute(ScreenBase const & screen, TCacheRouteArrowsCall if (glbHalfLen < glbHalfTextureLen) glbHalfLen = glbHalfTextureLen; - double const glbArrowHead = 2.0 * kArrowHeadSize * glbHalfTextureLen; - double const glbArrowTail = 2.0 * kArrowTailSize * glbHalfTextureLen; + double const glbArrowHead = 2.0 * kArrowHeadSize * glbHalfTextureLen; + double const glbArrowTail = 2.0 * kArrowTailSize * glbHalfTextureLen; double const glbMinArrowSize = glbArrowHead + glbArrowTail; double const kExtendCoef = 1.1; diff --git a/drape_frontend/route_shape.cpp b/drape_frontend/route_shape.cpp index 3e89716bfd..34ea6be236 100644 --- a/drape_frontend/route_shape.cpp +++ b/drape_frontend/route_shape.cpp @@ -21,9 +21,12 @@ namespace df namespace { -float const kLeftSide = 1.0; -float const kCenter = 0.0; -float const kRightSide = -1.0; +float const kLeftSide = 1.0f; +float const kCenter = 0.0f; +float const kRightSide = -1.0f; + +float const kRouteDepth = 100.0f; +float const kArrowsDepth = 200.0f; void GetArrowTextureRegion(ref_ptr textures, dp::TextureManager::SymbolRegion & region) { @@ -137,10 +140,14 @@ void RouteShape::PrepareGeometry(vector const & path, m2::PointD con segments.reserve(path.size() - 1); ConstructLineSegments(path, segmentsColors, segments); + if (segments.empty()) + return; + // Build geometry. - float length = 0; - float const kDepth = 0.0f; - for (size_t i = 0; i < segments.size(); i++) + float length = 0.0f; + float depth = 0.0f; + float const depthStep = kRouteDepth / (1 + segments.size()); + for (int i = static_cast(segments.size() - 1); i >= 0; i--) { UpdateNormals(&segments[i], (i > 0) ? &segments[i - 1] : nullptr, (i < segments.size() - 1) ? &segments[i + 1] : nullptr); @@ -151,8 +158,9 @@ void RouteShape::PrepareGeometry(vector const & path, m2::PointD con m2::PointD const endPt = MapShape::ConvertToLocal(glsl::FromVec2(segments[i].m_points[EndPoint]), pivot, kShapeCoordScalar); - glsl::vec3 const startPivot = glsl::vec3(glsl::ToVec2(startPt), kDepth); - glsl::vec3 const endPivot = glsl::vec3(glsl::ToVec2(endPt), kDepth); + glsl::vec3 const startPivot = glsl::vec3(glsl::ToVec2(startPt), depth); + glsl::vec3 const endPivot = glsl::vec3(glsl::ToVec2(endPt), depth); + depth += depthStep; float const endLength = length + glsl::length(segments[i].m_points[EndPoint] - segments[i].m_points[StartPoint]); @@ -177,7 +185,7 @@ void RouteShape::PrepareGeometry(vector const & path, m2::PointD con geometry.push_back(RV(endPivot, glsl::vec2(0, 0), glsl::vec3(endLength, 0, kCenter), segments[i].m_color)); // Generate joins. - if (segments[i].m_generateJoin && i < segments.size() - 1) + if (segments[i].m_generateJoin && i < static_cast(segments.size()) - 1) { glsl::vec2 n1 = segments[i].m_hasLeftJoin[EndPoint] ? segments[i].m_leftNormals[EndPoint] : segments[i].m_rightNormals[EndPoint]; @@ -228,7 +236,7 @@ void RouteShape::PrepareGeometry(vector const & path, m2::PointD con } void RouteShape::PrepareArrowGeometry(vector const & path, m2::PointD const & pivot, - m2::RectF const & texRect, float depth, + m2::RectF const & texRect, float depthStep, float depth, TArrowGeometryBuffer & geometry, TArrowGeometryBuffer & joinsGeometry) { ASSERT(path.size() > 1, ()); @@ -243,6 +251,7 @@ void RouteShape::PrepareArrowGeometry(vector const & path, m2::Point tr.setMaxX(texRect.minX() * kArrowHeadSize + texRect.maxX() * (1.0 - kArrowHeadSize)); // Build geometry. + float const depthInc = depthStep / (segments.size() + 1); for (size_t i = 0; i < segments.size(); i++) { UpdateNormals(&segments[i], (i > 0) ? &segments[i - 1] : nullptr, @@ -256,6 +265,7 @@ void RouteShape::PrepareArrowGeometry(vector const & path, m2::Point glsl::vec4 const startPivot = glsl::vec4(glsl::ToVec2(startPt), depth, 1.0); glsl::vec4 const endPivot = glsl::vec4(glsl::ToVec2(endPt), depth, 1.0); + depth += depthInc; glsl::vec2 const leftNormalStart = GetNormal(segments[i], true /* isLeft */, StartNormal); glsl::vec2 const rightNormalStart = GetNormal(segments[i], false /* isLeft */, StartNormal); @@ -312,7 +322,9 @@ void RouteShape::PrepareArrowGeometry(vector const & path, m2::Point }; float const u = 1.0f - kArrowHeadSize; vector uv = { glsl::vec2(u, 1.0f), glsl::vec2(u, 0.0f), glsl::vec2(1.0f, 0.5f) }; - GenerateArrowsTriangles(endPivot, normals, texRect, uv, true /* normalizedUV */, joinsGeometry); + glsl::vec4 const headPivot = glsl::vec4(glsl::ToVec2(endPt), depth, 1.0); + depth += depthInc; + GenerateArrowsTriangles(headPivot, normals, texRect, uv, true /* normalizedUV */, joinsGeometry); } // Generate arrow tail. @@ -391,13 +403,15 @@ void RouteShape::CacheRouteArrows(ref_ptr mng, m2::PolylineD state.SetColorTexture(region.GetTexture()); // Generate arrow geometry. - float depth = 0.0f; + float depth = kArrowsDepth; + float const depthStep = (kArrowsDepth - kRouteDepth) / (1 + borders.size()); for (ArrowBorders const & b : borders) { + depth -= depthStep; vector points = CalculatePoints(polyline, b.m_startDistance, b.m_endDistance); ASSERT_LESS_OR_EQUAL(points.size(), polyline.GetSize(), ()); - PrepareArrowGeometry(points, routeArrowsData.m_pivot, region.GetTexRect(), depth, geometry, joinsGeometry); - depth += 1.0f; + PrepareArrowGeometry(points, routeArrowsData.m_pivot, region.GetTexRect(), depthStep, + depth, geometry, joinsGeometry); } BatchGeometry(state, make_ref(geometry.data()), geometry.size(), diff --git a/drape_frontend/route_shape.hpp b/drape_frontend/route_shape.hpp index 29b2116692..edd7fe4a2d 100644 --- a/drape_frontend/route_shape.hpp +++ b/drape_frontend/route_shape.hpp @@ -18,17 +18,21 @@ namespace df { -double const kArrowSize = 0.001; +double const kArrowSize = 0.0008; // Constants below depend on arrow texture. -double const kArrowHeadSize = 124.0 / 400.0; -float const kArrowHeadFactor = 124.0f / 96.0f; +double const kArrowTextureWidth = 74.0; +double const kArrowTextureHeight = 44.0; +double const kArrowBodyHeight = 24.0; +double const kArrowHeadTextureWidth = 32.0; +double const kArrowTailTextureWidth = 4.0; -double const kArrowTailSize = 20.0 / 400.0; -float const kArrowTailFactor = 20.0f / 96.0f; - -double const kArrowHeightFactor = 96.0 / 36.0; -double const kArrowAspect = 400.0 / 192.0; +double const kArrowHeadSize = kArrowHeadTextureWidth / kArrowTextureWidth; +float const kArrowHeadFactor = 2.0 * kArrowHeadTextureWidth / kArrowTextureHeight; +double const kArrowTailSize = kArrowTailTextureWidth / kArrowTextureWidth; +float const kArrowTailFactor = 2.0 * kArrowTailTextureWidth / kArrowTextureHeight; +double const kArrowHeightFactor = kArrowTextureHeight / kArrowBodyHeight; +double const kArrowAspect = kArrowTextureWidth / kArrowTextureHeight; struct RoutePattern { @@ -108,7 +112,7 @@ private: TGeometryBuffer & geometry, TGeometryBuffer & joinsGeometry, double & outputLength); static void PrepareArrowGeometry(vector const & path, m2::PointD const & pivot, - m2::RectF const & texRect, float depth, + m2::RectF const & texRect, float depthStep, float depth, TArrowGeometryBuffer & geometry, TArrowGeometryBuffer & joinsGeometry); static void BatchGeometry(dp::GLState const & state, ref_ptr geometry, size_t geomSize, ref_ptr joinsGeometry, size_t joinsGeomSize, diff --git a/drape_frontend/traffic_renderer.cpp b/drape_frontend/traffic_renderer.cpp index 634a2f899a..c3ab0c3c08 100644 --- a/drape_frontend/traffic_renderer.cpp +++ b/drape_frontend/traffic_renderer.cpp @@ -155,7 +155,6 @@ void TrafficRenderer::RenderTraffic(ScreenBase const & screen, int zoomLevel, fl dp::Color const darkArrowColor = df::GetColorConstant(style, df::TrafficArrowDark); dp::Color const outlineColor = df::GetColorConstant(style, df::TrafficOutline); - GLFunctions::glClearDepth(); for (TrafficRenderData & renderData : m_renderData) { if (renderData.m_state.GetDrawAsLine())