diff --git a/drape/shaders/area3d_vertex_shader.vsh b/drape/shaders/area3d_vertex_shader.vsh new file mode 100644 index 0000000000..58352a9286 --- /dev/null +++ b/drape/shaders/area3d_vertex_shader.vsh @@ -0,0 +1,33 @@ +attribute vec3 a_position; +attribute vec3 a_normal; +attribute vec2 a_colorTexCoords; + +uniform mat4 modelView; +uniform mat4 projection; +uniform mat4 pivotTransform; + +varying vec2 v_colorTexCoords; +varying float v_intensity; + +const vec4 lightDir = vec4(1.0, 0.0, 3.0, 0.0); + +void main(void) +{ + vec4 pos = vec4(a_position, 1.0) * modelView; + vec4 pos_dx = vec4(a_position.x + 1.0, a_position.y, 0.0, 1.0) * modelView; + vec2 dx = pos_dx.xy / pos_dx.w - pos.xy / pos.w; + + float zScale = projection[0][0] * length(dx); + + vec4 normal = vec4(a_position + a_normal, 1.0) * modelView; + normal.xyw = (normal * projection).xyw; + normal.z = normal.z * zScale; + + pos.xyw = (pos * projection).xyw; + pos.z = a_position.z * zScale; + + v_intensity = max(0.0, -dot(normalize(lightDir), normalize(normal - pos))); + + gl_Position = pivotTransform * pos; + v_colorTexCoords = a_colorTexCoords; +} diff --git a/drape/shaders/area_vertex_shader.vsh b/drape/shaders/area_vertex_shader.vsh index 32142eedc0..e1866d5fae 100644 --- a/drape/shaders/area_vertex_shader.vsh +++ b/drape/shaders/area_vertex_shader.vsh @@ -16,7 +16,7 @@ void main(void) { vec4 pos = vec4(a_position, 1) * modelView * projection; float w = pos.w; - pos.xyw = (pivotTransform * pos).xyw; + pos.xyw = (pivotTransform * vec4(pos.xy, 0.0, w)).xyw; pos.z *= pos.w / w; gl_Position = pos; #ifdef ENABLE_VTF diff --git a/drape/shaders/arrow3d_vertex_shader.vsh b/drape/shaders/arrow3d_vertex_shader.vsh index 0d49a93ea9..1fd6741a9c 100644 --- a/drape/shaders/arrow3d_vertex_shader.vsh +++ b/drape/shaders/arrow3d_vertex_shader.vsh @@ -5,7 +5,7 @@ uniform mat4 m_transform; varying float v_intensity; -const vec4 lightDir = vec4(1.0, 0.0, 1.0, 0.0); +const vec4 lightDir = vec4(1.0, 0.0, 3.0, 0.0); void main() { diff --git a/drape/shaders/circle_shader.vsh b/drape/shaders/circle_shader.vsh index c191f681fe..23be8dff96 100644 --- a/drape/shaders/circle_shader.vsh +++ b/drape/shaders/circle_shader.vsh @@ -18,7 +18,7 @@ void main(void) { vec4 pos = (vec4(a_normal.xy, 0, 0) + vec4(a_position, 1) * modelView) * projection; float w = pos.w; - pos.xyw = (pivotTransform * pos).xyw; + pos.xyw = (pivotTransform * vec4(pos.xy, 0.0, w)).xyw; pos.z *= pos.w / w; gl_Position = pos; #ifdef ENABLE_VTF diff --git a/drape/shaders/dashed_vertex_shader.vsh b/drape/shaders/dashed_vertex_shader.vsh index ab3bd09a9c..5704469871 100644 --- a/drape/shaders/dashed_vertex_shader.vsh +++ b/drape/shaders/dashed_vertex_shader.vsh @@ -29,7 +29,7 @@ void main(void) v_halfLength = vec2(sign(a_normal.z) * halfWidth, abs(a_normal.z)); vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * projection; float w = pos.w; - pos.xyw = (pivotTransform * pos).xyw; + pos.xyw = (pivotTransform * vec4(pos.xy, 0.0, w)).xyw; pos.z *= pos.w / w; gl_Position = pos; } diff --git a/drape/shaders/line_vertex_shader.vsh b/drape/shaders/line_vertex_shader.vsh index 7c5a6a6398..9aa9ea763c 100644 --- a/drape/shaders/line_vertex_shader.vsh +++ b/drape/shaders/line_vertex_shader.vsh @@ -35,7 +35,7 @@ void main(void) v_halfLength = vec2(sign(a_normal.z) * halfWidth, abs(a_normal.z)); vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * projection; float w = pos.w; - pos.xyw = (pivotTransform * pos).xyw; + pos.xyw = (pivotTransform * vec4(pos.xy, 0.0, w)).xyw; pos.z *= pos.w / w; gl_Position = pos; } diff --git a/drape/shaders/my_position_shader.vsh b/drape/shaders/my_position_shader.vsh index ec22b0856d..eabd2537f0 100644 --- a/drape/shaders/my_position_shader.vsh +++ b/drape/shaders/my_position_shader.vsh @@ -27,7 +27,7 @@ void main(void) shiftedPos = shiftedPos * projection; float w = shiftedPos.w; - shiftedPos.xyw = (pivotTransform * shiftedPos).xyw; + shiftedPos.xyw = (pivotTransform * vec4(shiftedPos.xy, 0.0, w)).xyw; shiftedPos.z *= shiftedPos.w / w; gl_Position = shiftedPos; v_colorTexCoords = a_colorTexCoords; diff --git a/drape/shaders/path_symbol_vertex_shader.vsh b/drape/shaders/path_symbol_vertex_shader.vsh index ee69da854a..ee0709bd23 100644 --- a/drape/shaders/path_symbol_vertex_shader.vsh +++ b/drape/shaders/path_symbol_vertex_shader.vsh @@ -15,7 +15,7 @@ void main(void) highp vec4 shiftedPos = norm + pos; shiftedPos = shiftedPos * projection; float w = shiftedPos.w; - shiftedPos.xyw = (pivotTransform * pos).xyw; + shiftedPos.xyw = (pivotTransform * vec4(shiftedPos.xy, 0.0, w)).xyw; shiftedPos.z *= shiftedPos.w / w; gl_Position = shiftedPos; v_colorTexCoords = a_colorTexCoords; diff --git a/drape/shaders/plane3d_fragment_shader.fsh b/drape/shaders/plane3d_fragment_shader.fsh new file mode 100644 index 0000000000..89b9629911 --- /dev/null +++ b/drape/shaders/plane3d_fragment_shader.fsh @@ -0,0 +1,7 @@ +uniform sampler2D tex; +varying vec2 v_tcoord; + +void main() +{ + gl_FragColor = texture2D(tex, v_tcoord); +} diff --git a/drape/shaders/texturing3d_vertex_shader.vsh b/drape/shaders/plane3d_vertex_shader.vsh similarity index 100% rename from drape/shaders/texturing3d_vertex_shader.vsh rename to drape/shaders/plane3d_vertex_shader.vsh diff --git a/drape/shaders/position_accuracy_shader.vsh b/drape/shaders/position_accuracy_shader.vsh index 1a09eca553..bd2b58b05b 100644 --- a/drape/shaders/position_accuracy_shader.vsh +++ b/drape/shaders/position_accuracy_shader.vsh @@ -16,7 +16,7 @@ void main(void) vec4 normal = vec4(normalize(a_normal) * u_accuracy, 0.0, 0.0); position = (position + normal) * projection; float w = position.w; - position.xyw = (pivotTransform * position).xyw; + position.xyw = (pivotTransform * vec4(position.xy, 0.0, w)).xyw; position.z *= position.w / w; gl_Position = position; diff --git a/drape/shaders/route_vertex_shader.vsh b/drape/shaders/route_vertex_shader.vsh index b8363c396f..0c8cd4f0e7 100644 --- a/drape/shaders/route_vertex_shader.vsh +++ b/drape/shaders/route_vertex_shader.vsh @@ -31,7 +31,7 @@ void main(void) v_length = vec3(len, u_routeParams.z); vec4 pos = vec4(transformedAxisPos, a_position.z, 1.0) * projection; float w = pos.w; - pos.xyw = (pivotTransform * pos).xyw; + pos.xyw = (pivotTransform * vec4(pos.xy, 0.0, w)).xyw; pos.z *= pos.w / w; gl_Position = pos; } diff --git a/drape/shaders/shader_index.txt b/drape/shaders/shader_index.txt index 1cf173a91b..e6e8ba5112 100644 --- a/drape/shaders/shader_index.txt +++ b/drape/shaders/shader_index.txt @@ -2,6 +2,7 @@ TEXT_OUTLINED_PROGRAM text_outlined_vertex_shader.vsh text_fragment_shader.fsh TEXT_PROGRAM text_vertex_shader.vsh text_fragment_shader.fsh TEXT_OUTLINED_GUI_PROGRAM text_outlined_gui_vertex_shader.vsh text_fragment_shader.fsh AREA_PROGRAM area_vertex_shader.vsh solid_color_fragment_shader.fsh +AREA_3D_PROGRAM area3d_vertex_shader.vsh texturing3d_fragment_shader.fsh TEXTURING_PROGRAM texturing_vertex_shader.vsh texturing_fragment_shader.fsh LINE_PROGRAM line_vertex_shader.vsh line_fragment_shader.fsh CAP_JOIN_PROGRAM circle_shader.vsh circle_shader.fsh @@ -17,6 +18,7 @@ ROUTE_PROGRAM route_vertex_shader.vsh route_fragment_shader.fsh ROUTE_ARROW_PROGRAM route_vertex_shader.vsh route_arrow_fragment_shader.fsh DEBUG_RECT_PROGRAM debug_rect_vertex_shader.vsh debug_rect_fragment_shader.fsh TEXTURING_3D_PROGRAM texturing3d_vertex_shader.vsh texturing3d_fragment_shader.fsh +PLANE_3D_PROGRAM plane3d_vertex_shader.vsh plane3d_fragment_shader.fsh ARROW_3D_PROGRAM arrow3d_vertex_shader.vsh arrow3d_fragment_shader.fsh TEXTURING_BILLBOARD_PROGRAM texturing_billboard_vertex_shader.vsh texturing_fragment_shader.fsh TEXT_OUTLINED_BILLBOARD_PROGRAM text_outlined_billboard_vertex_shader.vsh text_fragment_shader.fsh diff --git a/drape/shaders/text_billboard_vertex_shader.vsh b/drape/shaders/text_billboard_vertex_shader.vsh index d6d6fc4f69..a655997f05 100755 --- a/drape/shaders/text_billboard_vertex_shader.vsh +++ b/drape/shaders/text_billboard_vertex_shader.vsh @@ -28,8 +28,8 @@ void main() vec4 offset = vec4(a_normal, Zero, Zero) * projection; vec4 projectedPivot = pivot * projection; - vec4 transformedPivot = pivotTransform * projectedPivot; - + vec4 transformedPivot = pivotTransform * vec4(projectedPivot.xy, 0.0, 1.0); + vec4 scale = pivotTransform * vec4(One, -One, Zero, One); gl_Position = transformedPivot + vec4(offset.xy * transformedPivot.w / scale.w * scale.x, Zero, Zero); diff --git a/drape/shaders/text_vertex_shader.vsh b/drape/shaders/text_vertex_shader.vsh index f548dd04d6..fbc85ef453 100644 --- a/drape/shaders/text_vertex_shader.vsh +++ b/drape/shaders/text_vertex_shader.vsh @@ -28,7 +28,7 @@ void main() highp vec4 shiftedPos = vec4(a_normal, Zero, Zero) + pos; shiftedPos = shiftedPos * projection; float w = shiftedPos.w; - shiftedPos.xyw = (pivotTransform * shiftedPos).xyw; + shiftedPos.xyw = (pivotTransform * vec4(shiftedPos.xy, 0.0, w)).xyw; shiftedPos.z *= shiftedPos.w / w; gl_Position = shiftedPos; diff --git a/drape/shaders/texturing3d_fragment_shader.fsh b/drape/shaders/texturing3d_fragment_shader.fsh index 89b9629911..f50096f568 100644 --- a/drape/shaders/texturing3d_fragment_shader.fsh +++ b/drape/shaders/texturing3d_fragment_shader.fsh @@ -1,7 +1,12 @@ -uniform sampler2D tex; -varying vec2 v_tcoord; +uniform sampler2D u_colorTex; +uniform float u_opacity; -void main() +varying vec2 v_colorTexCoords; +varying float v_intensity; + +void main(void) { - gl_FragColor = texture2D(tex, v_tcoord); + vec4 finalColor = texture2D(u_colorTex, v_colorTexCoords); + finalColor.a *= u_opacity; + gl_FragColor = vec4((v_intensity * 0.2 + 0.8) * finalColor.rgb, finalColor.a); } diff --git a/drape/shaders/texturing_billboard_vertex_shader.vsh b/drape/shaders/texturing_billboard_vertex_shader.vsh index 8ae2eb5b35..fa901f6ec9 100644 --- a/drape/shaders/texturing_billboard_vertex_shader.vsh +++ b/drape/shaders/texturing_billboard_vertex_shader.vsh @@ -16,7 +16,7 @@ void main(void) vec4 offset = vec4(a_normal, 0, 0) * projection; vec4 projectedPivot = pivot * projection; - vec4 transformedPivot = pivotTransform * projectedPivot; + vec4 transformedPivot = pivotTransform * vec4(projectedPivot.xy, 0.0, 1.0); vec4 scale = pivotTransform * vec4(1.0, -1.0, 0, 1.0); gl_Position = transformedPivot + vec4(offset.xy * transformedPivot.w / scale.w * scale.x, 0, 0); diff --git a/drape/shaders/texturing_vertex_shader.vsh b/drape/shaders/texturing_vertex_shader.vsh index 185666ee12..884aa07476 100644 --- a/drape/shaders/texturing_vertex_shader.vsh +++ b/drape/shaders/texturing_vertex_shader.vsh @@ -16,7 +16,7 @@ void main(void) highp vec4 shiftedPos = vec4(a_normal, 0, 0) + pos; shiftedPos = shiftedPos * projection; float w = shiftedPos.w; - shiftedPos.xyw = (pivotTransform * shiftedPos).xyw; + shiftedPos.xyw = (pivotTransform * vec4(shiftedPos.xy, 0.0, w)).xyw; shiftedPos.z *= shiftedPos.w / w; gl_Position = shiftedPos; v_colorTexCoords = a_colorTexCoords; diff --git a/drape/shaders/user_mark.vsh b/drape/shaders/user_mark.vsh index 530b4360f4..724fef0756 100644 --- a/drape/shaders/user_mark.vsh +++ b/drape/shaders/user_mark.vsh @@ -18,7 +18,7 @@ void main(void) vec4 pos = (vec4(normal, 0, 0) + vec4(a_position, 1) * modelView) * projection; float w = pos.w; - pos.xyw = (pivotTransform * pos).xyw; + pos.xyw = (pivotTransform * vec4(pos.xy, 0.0, w)).xyw; pos.z *= pos.w / w; gl_Position = pos; v_colorTexCoords = a_colorTexCoords; diff --git a/drape/shaders/user_mark_billboard.vsh b/drape/shaders/user_mark_billboard.vsh index 4588072125..4ad8aa043d 100644 --- a/drape/shaders/user_mark_billboard.vsh +++ b/drape/shaders/user_mark_billboard.vsh @@ -20,7 +20,7 @@ void main(void) vec4 offset = vec4(normal, 0, 0) * projection; vec4 projectedPivot = pivot * projection; - vec4 transformedPivot = pivotTransform * projectedPivot; + vec4 transformedPivot = pivotTransform * vec4(projectedPivot.xy, 0.0, 1.0); vec4 scale = pivotTransform * vec4(1.0, -1.0, 0, 1.0); gl_Position = transformedPivot + vec4(offset.xy * transformedPivot.w / scale.w * scale.x, 0, 0); diff --git a/drape/utils/vertex_decl.cpp b/drape/utils/vertex_decl.cpp index 40a8519cab..c533790843 100644 --- a/drape/utils/vertex_decl.cpp +++ b/drape/utils/vertex_decl.cpp @@ -9,6 +9,7 @@ namespace enum VertexType { Area, + Area3d, SolidTexturing, TextStatic, TextOutlinedStatic, @@ -33,8 +34,22 @@ dp::BindingInfo AreaBindingInit() sizeof(AreaVertex::TTexCoord)), ""); dp::BindingFiller filler(2); - filler.FillDecl("a_position"); - filler.FillDecl("a_colorTexCoords"); + filler.FillDecl("a_position"); + filler.FillDecl("a_colorTexCoords"); + + return filler.m_info; +} + +dp::BindingInfo Area3dBindingInit() +{ + static_assert(sizeof(Area3dVertex) == (sizeof(Area3dVertex::TPosition) + + sizeof(Area3dVertex::TNormal3d) + + sizeof(Area3dVertex::TTexCoord)), ""); + + dp::BindingFiller filler(3); + filler.FillDecl("a_position"); + filler.FillDecl("a_normal"); + filler.FillDecl("a_colorTexCoords"); return filler.m_info; } @@ -135,6 +150,7 @@ BindingNode g_bindingNodes[TypeCount]; TInitFunction g_initFunctions[TypeCount] = { &AreaBindingInit, + &Area3dBindingInit, &SolidTexturingBindingInit, &TextStaticBindingInit, &TextOutlinedStaticBindingInit, @@ -175,6 +191,26 @@ dp::BindingInfo const & AreaVertex::GetBindingInfo() return GetBinding(Area); } +Area3dVertex::Area3dVertex() + : m_position(0.0, 0.0, 0.0) + , m_normal(0.0, 0.0, 0.0) + , m_colorTexCoord(0.0, 0.0) +{ +} + +Area3dVertex::Area3dVertex(TPosition const & position, TPosition const & normal, + TTexCoord const & colorTexCoord) + : m_position(position) + , m_normal(normal) + , m_colorTexCoord(colorTexCoord) +{ +} + +dp::BindingInfo const & Area3dVertex::GetBindingInfo() +{ + return GetBinding(Area3d); +} + SolidTexturingVertex::SolidTexturingVertex() : m_position(0.0, 0.0, 0.0) , m_normal(0.0, 0.0) diff --git a/drape/utils/vertex_decl.hpp b/drape/utils/vertex_decl.hpp index 90aa14d08b..296a1d81ab 100644 --- a/drape/utils/vertex_decl.hpp +++ b/drape/utils/vertex_decl.hpp @@ -12,6 +12,7 @@ struct BaseVertex { using TPosition = glsl::vec3; using TNormal = glsl::vec2; + using TNormal3d = glsl::vec3; using TTexCoord = glsl::vec2; }; @@ -26,6 +27,18 @@ struct AreaVertex : BaseVertex static dp::BindingInfo const & GetBindingInfo(); }; +struct Area3dVertex : BaseVertex +{ + Area3dVertex(); + Area3dVertex(TPosition const & position, const TPosition & normal, TTexCoord const & colorTexCoord); + + TPosition m_position; + TNormal3d m_normal; + TTexCoord m_colorTexCoord; + + static dp::BindingInfo const & GetBindingInfo(); +}; + struct SolidTexturingVertex : BaseVertex { SolidTexturingVertex(); diff --git a/drape_frontend/apply_feature_functors.cpp b/drape_frontend/apply_feature_functors.cpp index eecab78bad..acec40a23f 100644 --- a/drape_frontend/apply_feature_functors.cpp +++ b/drape_frontend/apply_feature_functors.cpp @@ -364,12 +364,15 @@ bool ApplyAreaFeature::EqualEdges(TEdge const & edge1, TEdge const & edge2) cons (edge1.first == edge2.second && edge1.second == edge2.first); } -bool ApplyAreaFeature::FindEdge(TEdge const & edge) const +bool ApplyAreaFeature::FindEdge(TEdge const & edge) { for (size_t i = 0; i < m_edges.size(); i++) { if (EqualEdges(m_edges[i].first, edge)) + { + m_edges[i].second = -1; return true; + } } return false; } @@ -379,7 +382,7 @@ m2::PointD ApplyAreaFeature::CalculateNormal(m2::PointD const & p1, m2::PointD c m2::PointD const tangent = (p2 - p1).Normalize(); m2::PointD normal = m2::PointD(-tangent.y, tangent.x); m2::PointD const v = ((p1 + p2) * 0.5 - p3).Normalize(); - if (m2::CrossProduct(normal, v) < 0.0) + if (m2::DotProduct(normal, v) < 0.0) normal = -normal; return normal; @@ -408,6 +411,8 @@ void ApplyAreaFeature::CalculateBuildingEdges(vector & edges) { for (auto & e : m_edges) { + if (e.second < 0) + continue; BuildingEdge edge; edge.m_startVertex = m_indices[e.first.first]; edge.m_endVertex = m_indices[e.first.second]; diff --git a/drape_frontend/apply_feature_functors.hpp b/drape_frontend/apply_feature_functors.hpp index ab1bea6ae8..0a43f6bdfb 100644 --- a/drape_frontend/apply_feature_functors.hpp +++ b/drape_frontend/apply_feature_functors.hpp @@ -89,7 +89,7 @@ private: int GetIndex(m2::PointD const & pt); void BuildEdges(int vertexIndex1, int vertexIndex2, int vertexIndex3); bool EqualEdges(TEdge const & edge1, TEdge const & edge2) const; - bool FindEdge(TEdge const & edge) const; + bool FindEdge(TEdge const & edge); m2::PointD CalculateNormal(m2::PointD const & p1, m2::PointD const & p2, m2::PointD const & p3) const; vector m_triangles; diff --git a/drape_frontend/area_shape.cpp b/drape_frontend/area_shape.cpp index c4ee383a87..e20b004735 100644 --- a/drape_frontend/area_shape.cpp +++ b/drape_frontend/area_shape.cpp @@ -29,20 +29,59 @@ void AreaShape::Draw(ref_ptr batcher, ref_ptr t textures->GetColorRegion(m_params.m_color, region); glsl::vec2 const colorPoint = glsl::ToVec2(region.GetTexRect().Center()); - buffer_vector vertexes; - vertexes.resize(m_vertexes.size()); - transform(m_vertexes.begin(), m_vertexes.end(), vertexes.begin(), [&colorPoint, this](m2::PointF const & vertex) + if (!m_buildingEdges.empty()) { - return gpu::AreaVertex(glsl::vec3(glsl::ToVec2(vertex), m_params.m_depth), - colorPoint); - }); + vector vertexes; + vertexes.reserve(m_vertexes.size() + m_buildingEdges.size() * 6); - dp::GLState state(gpu::AREA_PROGRAM, dp::GLState::GeometryLayer); - state.SetColorTexture(region.GetTexture()); + float const kBuildingHeight = 0.0008 * (1.0 + 2.0 * rand() / RAND_MAX);//(m_buildingEdges[0].m_startVertex - m_buildingEdges[0].m_endVertex).Length(); + for (auto const & edge : m_buildingEdges) + { + glsl::vec3 normal(glsl::ToVec2(edge.m_normal), 0.0f); + vertexes.push_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_startVertex), 0.0f), + normal, colorPoint)); + vertexes.push_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_endVertex), 0.0f), + normal, colorPoint)); + vertexes.push_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_startVertex), -kBuildingHeight), + normal, colorPoint)); - dp::AttributeProvider provider(1, m_vertexes.size()); - provider.InitStream(0, gpu::AreaVertex::GetBindingInfo(), make_ref(vertexes.data())); - batcher->InsertTriangleList(state, make_ref(&provider)); + vertexes.push_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_startVertex), -kBuildingHeight), + normal, colorPoint)); + vertexes.push_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_endVertex), 0.0f), + normal, colorPoint)); + vertexes.push_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(edge.m_endVertex), -kBuildingHeight), + normal, colorPoint)); + } + + glsl::vec3 normal(0.0f, 0.0f, -1.0f); + for (auto const & vertex : m_vertexes) + vertexes.push_back(gpu::Area3dVertex(glsl::vec3(glsl::ToVec2(vertex), -kBuildingHeight), + normal, colorPoint)); + + dp::GLState state(gpu::AREA_3D_PROGRAM, dp::GLState::GeometryLayer); + state.SetColorTexture(region.GetTexture()); + + dp::AttributeProvider provider(1, vertexes.size()); + provider.InitStream(0, gpu::Area3dVertex::GetBindingInfo(), make_ref(vertexes.data())); + batcher->InsertTriangleList(state, make_ref(&provider)); + } + else + { + buffer_vector vertexes; + vertexes.resize(m_vertexes.size()); + transform(m_vertexes.begin(), m_vertexes.end(), vertexes.begin(), [&colorPoint, this](m2::PointF const & vertex) + { + return gpu::AreaVertex(glsl::vec3(glsl::ToVec2(vertex), m_params.m_depth), + colorPoint); + }); + + dp::GLState state(gpu::AREA_PROGRAM, dp::GLState::GeometryLayer); + state.SetColorTexture(region.GetTexture()); + + dp::AttributeProvider provider(1, m_vertexes.size()); + provider.InitStream(0, gpu::AreaVertex::GetBindingInfo(), make_ref(vertexes.data())); + batcher->InsertTriangleList(state, make_ref(&provider)); + } } } // namespace df diff --git a/drape_frontend/frontend_renderer.cpp b/drape_frontend/frontend_renderer.cpp index 728396a3e5..0e79948417 100755 --- a/drape_frontend/frontend_renderer.cpp +++ b/drape_frontend/frontend_renderer.cpp @@ -6,6 +6,7 @@ #include "drape_frontend/user_mark_shapes.hpp" #include "drape/debug_rect_renderer.hpp" +#include "drape/shader_def.hpp" #include "drape/support_manager.hpp" #include "drape/utils/glyph_usage_tracker.hpp" @@ -494,6 +495,16 @@ void FrontendRenderer::AcceptMessage(ref_ptr message) case Message::Allow3dMode: { ref_ptr const msg = message; +#ifdef OMIM_OS_DESKTOP + if (m_enable3dInNavigation == msg->Enable()) + { + if (m_enable3dInNavigation) + AddUserEvent(EnablePerspectiveEvent(M_PI / 4.0, M_PI / 3.0, + false /* animated */, true /* immediately start */)); + else + AddUserEvent(DisablePerspectiveEvent()); + } +#endif m_enable3dInNavigation = msg->Enable(); break; } @@ -725,6 +736,10 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) drape_ptr const & group = m_renderGroups[currentRenderGroup]; dp::GLState const & state = group->GetState(); + + if (isPerspective && state.GetProgram3dIndex() == gpu::AREA_3D_PROGRAM) + continue; + dp::GLState::DepthLayer layer = state.GetDepthLayer(); if (prevLayer != layer && layer == dp::GLState::OverlayLayer) break; @@ -752,8 +767,7 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) modelView, make_ref(m_gpuProgramManager), m_generalUniforms); GLFunctions::glEnable(gl_const::GLDepthTest); - if (isPerspective) - GLFunctions::glClearDepth(); + GLFunctions::glClearDepth(); for (; currentRenderGroup < m_renderGroups.size(); ++currentRenderGroup) { drape_ptr const & group = m_renderGroups[currentRenderGroup]; @@ -775,6 +789,19 @@ void FrontendRenderer::RenderScene(ScreenBase const & modelView) m_routeRenderer->RenderRouteSigns(modelView, make_ref(m_gpuProgramManager), m_generalUniforms); + + if (isPerspective) + { + GLFunctions::glEnable(gl_const::GLDepthTest); + for (currentRenderGroup = 0; currentRenderGroup < m_renderGroups.size(); ++currentRenderGroup) + { + drape_ptr const & group = m_renderGroups[currentRenderGroup]; + + if (isPerspective && group->GetState().GetProgram3dIndex() == gpu::AREA_3D_PROGRAM) + RenderSingleGroup(modelView, make_ref(group)); + } + } + m_myPositionController->Render(MyPositionController::RenderMyPosition, modelView, make_ref(m_gpuProgramManager), m_generalUniforms); @@ -836,10 +863,6 @@ void FrontendRenderer::RefreshPivotTransform(ScreenBase const & screen) if (screen.isPerspective()) { math::Matrix transform(screen.Pto3dMatrix()); - math::Matrix scaleM = math::Identity(); - scaleM(2, 2) = 0.0; - - transform = scaleM * transform; m_generalUniforms.SetMatrix4x4Value("pivotTransform", transform.m_data); } else diff --git a/drape_frontend/renderer3d.cpp b/drape_frontend/renderer3d.cpp index ee304097bb..407bb5c46d 100644 --- a/drape_frontend/renderer3d.cpp +++ b/drape_frontend/renderer3d.cpp @@ -66,7 +66,7 @@ void Renderer3d::Build(ref_ptr prg) void Renderer3d::Render(ScreenBase const & screen, uint32_t textureId, ref_ptr mng) { - ref_ptr prg = mng->GetProgram(gpu::TEXTURING_3D_PROGRAM); + ref_ptr prg = mng->GetProgram(gpu::PLANE_3D_PROGRAM); prg->Bind(); if (m_VAO == 0) diff --git a/geometry/geometry.pro b/geometry/geometry.pro index d51bfbb054..a8c15a3256 100644 --- a/geometry/geometry.pro +++ b/geometry/geometry.pro @@ -47,3 +47,4 @@ HEADERS += \ transformations.hpp \ tree4d.hpp \ triangle2d.hpp \ + point3d.hpp diff --git a/geometry/point3d.hpp b/geometry/point3d.hpp new file mode 100644 index 0000000000..f1a7927f1b --- /dev/null +++ b/geometry/point3d.hpp @@ -0,0 +1,279 @@ +#pragma once + +#include "base/assert.hpp" +#include "base/base.hpp" +#include "base/math.hpp" +#include "base/matrix.hpp" + +#include "std/array.hpp" +#include "std/cmath.hpp" +#include "std/functional.hpp" +#include "std/sstream.hpp" +#include "std/typeinfo.hpp" + + +namespace m3 +{ + template + class Point + { + public: + typedef T value_type; + + T x, y, z; + + Point() {} + Point(T x_, T y_, T z_) : x(x_), y(y_), z(z_) {} + template Point(Point const & u) : x(u.x), y(u.y), z(u.z) {} + + static Point Zero() { return Point(0, 0, 0, 0); } + + bool Equal(Point const & p, T eps) const + { + return ((fabs(x - p.x) < eps) && (fabs(y - p.y) < eps) && (fabs(z - p.z) < eps)); + } + + T SquareLength(Point const & p) const + { + return math::sqr(x- p.x) + math::sqr(y - p.y) + math::sqr(z - p.z); + } + + double Length(Point const & p) const + { + return sqrt(SquareLength(p)); + } + + Point MoveXY(T len, T ang) const + { + return Point(x + len * cos(ang), y + len * sin(ang), z, w); + } + + Point MoveXY(T len, T angSin, T angCos) const + { + return m3::Point(x + len * angCos, y + len * angSin, z, w); + } + + Point const & operator-=(Point const & a) + { + x -= a.x; + y -= a.y; + z -= a.z; + return *this; + } + + Point const & operator+=(Point const & a) + { + x += a.x; + y += a.y; + z += a.z; + return *this; + } + + template + Point const & operator*=(U const & k) + { + x = static_cast(x * k); + y = static_cast(y * k); + z = static_cast(z * k); + return *this; + } + + template + Point const & operator=(Point const & a) + { + x = static_cast(a.x); + y = static_cast(a.y); + z = static_cast(a.z); + return *this; + } + + bool operator == (m3::Point const & p) const + { + return x == p.x && y == p.y && z == p.z; + } + bool operator != (m3::Point const & p) const + { + return !(*this == p); + } + m3::Point operator + (m3::Point const & pt) const + { + return m3::Point(x + pt.x, y + pt.y, z + pt.z); + } + m3::Point operator - (m3::Point const & pt) const + { + return m3::Point(x - pt.x, y - pt.y, z - pt.z); + } + m3::Point operator -() const + { + return m3::Point(-x, -y, -z); + } + + m3::Point operator * (T scale) const + { + return m3::Point(x * scale, y * scale, z * scale); + } + + m3::Point const operator * (math::Matrix const & m) const + { + math::Matrix point = { x, y, z, 1}; + math::Matrix res = point * m; + return m3::Point(res(0, 0) / res(0, 3), res(0, 1) / res(0, 3), res(0, 2) / res(0, 3)); + } + + m3::Point operator / (T scale) const + { + return m3::Point(x / scale, y / scale, z / scale); + } + + m3::Point mid(m3::Point const & p) const + { + return m3::Point((x + p.x) * 0.5, (y + p.y) * 0.5, (z + p.z) * 0.5); + } + + /// @name VectorOperationsOnPoint + // @{ + double Length() const + { + return sqrt(x*x + y*y + z*z); + } + + Point Normalize() const + { + ASSERT(!IsAlmostZero(), ()); + double const module = this->Length(); + return Point(x / module, y / module, z / module); + } + // @} + + m3::Point const & operator *= (math::Matrix const & m) + { + math::Matrix point = { x, y, z, 1}; + math::Matrix res = point * m; + x = res(0, 0) / res(0, 3); + y = res(0, 1) / res(0, 3); + z = res(0, 2) / res(0, 3); + return *this; + } + + void RotateXY(double angle) + { + T cosAngle = cos(angle); + T sinAngle = sin(angle); + T oldX = x; + x = cosAngle * oldX - sinAngle * y; + y = sinAngle * oldX + cosAngle * y; + } + }; + + template + inline Point const operator- (Point const & a, Point const & b) + { + return Point(a.x - b.x, a.y - b.y, a.z - b.z); + } + + template + inline Point const operator+ (Point const & a, Point const & b) + { + return Point(a.x + b.x, a.y + b.y, a.x + b.z); + } + + template + Point const Cross(Point const & pt1, Point const & pt2) + { + Point const res(pt1.y * pt2.z - pt1.z * pt2.y, + pt1.z * pt2.x - pt1.x * pt2.z, + pt1.x * pt2.y - pt1.y * pt2.x; + return res; + } + + // Dot product of a and b, equals to |a|*|b|*cos(angle_between_a_and_b). + template + T const DotProduct(Point const & a, Point const & b) + { + return a.x * b.x + a.y * b.y + a.z * b.z; + } + + // Value of cross product of a and b, equals to |a|*|b|*sin(angle_between_a_and_b). + template + T const CrossProduct(Point const & a, Point const & b) + { + return Cross(a, b).Length(); + } + + template + Point const Shift(Point const & pt, U const & dx, U const & dy, U const & dz) + { + return Point(pt.x + dx, pt.y + dy, pt.z + dz); + } + + template + Point const Shift(Point const & pt, Point const & offset) + { + return Shift(pt, offset.x, offset.y, offset.z); + } + + template + Point const Floor(Point const & pt) + { + Point res; + res.x = floor(pt.x); + res.y = floor(pt.y); + res.z = floor(pt.z); + return res; + } + + template + int GetOrientation(PointT const & p1, PointT const & p2, PointT const & pt) + { + double const sa = CrossProduct(p1 - pt, p2 - pt); + if (sa > 0.0) + return 1; + if (sa < 0.0) + return -1; + return 0; + } + + template string DebugPrint(m3::Point const & p) + { + ostringstream out; + out.precision(20); + out << "m3::Point<" << typeid(T).name() << ">(" << p.x << ", " << p.y << ", " << p.z << ")"; + return out.str(); + } + + template + TArchive & operator >> (TArchive & ar, m3::Point & pt) + { + ar >> pt.x; + ar >> pt.y; + ar >> pt.z; + return ar; + } + + template + TArchive & operator << (TArchive & ar, m3::Point const & pt) + { + ar << pt.x; + ar << pt.y; + ar << pt.z; + return ar; + } + + template + bool operator< (Point const & l, Point const & r) + { + if (l.x != r.x) + return l.x < r.x; + if (l.y != r.y) + return l.y < r.y; + return l.z < r.z; + } + + typedef Point PointF; + typedef Point PointD; + typedef Point PointU; + typedef Point PointU64; + typedef Point PointI; + typedef Point PointI64; +} +