From 6bece13004e0c1b57d8e7f6f99606d7a435f8346 Mon Sep 17 00:00:00 2001 From: rachytski Date: Fri, 14 Jan 2011 02:27:25 +0200 Subject: [PATCH] Sticky touches navigation and heading drawing. --- geometry/point2d.hpp | 12 + iphone/Maps/Classes/MapViewController.hpp | 5 +- iphone/Maps/Classes/MapViewController.mm | 31 ++- .../Maps/Classes/UserLocationController.hpp | 3 +- iphone/Maps/Classes/UserLocationController.mm | 5 +- iphone/Maps/Maps.xcodeproj/project.pbxproj | 4 +- map/drawer_yg.cpp | 8 +- map/drawer_yg.hpp | 2 +- map/framework.hpp | 208 ++++++++++++------ qt/widgets.cpp | 4 +- yg/geometry_batcher.cpp | 4 +- yg/geometry_batcher.hpp | 9 +- yg/screen.hpp | 8 +- yg/shape_renderer.cpp | 68 ++++++ yg/shape_renderer.hpp | 23 ++ yg/text_renderer.cpp | 9 +- yg/text_renderer.hpp | 2 + yg/yg.pro | 6 +- yg/yg_tests/screengl_test.cpp | 21 +- 19 files changed, 319 insertions(+), 113 deletions(-) create mode 100644 yg/shape_renderer.cpp create mode 100644 yg/shape_renderer.hpp diff --git a/geometry/point2d.hpp b/geometry/point2d.hpp index 5f3fb3a449..5b6f819879 100644 --- a/geometry/point2d.hpp +++ b/geometry/point2d.hpp @@ -167,6 +167,18 @@ namespace m2 return res; } + template + Point const Shift(Point const & pt, U const & dx, U const & dy) + { + return Point(pt.x + dx, pt.y + dy); + } + + template + Point const Shift(Point const & pt, Point const & offset) + { + return Shift(pt, offset.x, offset.y); + } + template bool IsPointStrictlyInsideTriangle(Point const & p, Point const & a, Point const & b, Point const & c) diff --git a/iphone/Maps/Classes/MapViewController.hpp b/iphone/Maps/Classes/MapViewController.hpp index d8016ccd9e..b5603fd01b 100644 --- a/iphone/Maps/Classes/MapViewController.hpp +++ b/iphone/Maps/Classes/MapViewController.hpp @@ -22,6 +22,8 @@ } m_CurrentAction; bool m_isDirtyPosition; + bool m_isSticking; + size_t m_StickyThreshold; m2::PointD m_Pt1, m_Pt2; } @@ -31,8 +33,7 @@ - (void) OnLocation: (m2::PointD const &) mercatorPoint withConfidenceRadius: (double) confidenceRadius withTimestamp: (NSDate *) timestamp; -- (void) OnHeading: (double) heading - withTimestamp: (NSDate *) timestamp; +- (void) OnHeading: (CLHeading*) heading; - (void) OnLocationError: (NSString *) errorDescription; diff --git a/iphone/Maps/Classes/MapViewController.mm b/iphone/Maps/Classes/MapViewController.mm index cad1995b1f..749d23284b 100644 --- a/iphone/Maps/Classes/MapViewController.mm +++ b/iphone/Maps/Classes/MapViewController.mm @@ -60,6 +60,7 @@ typedef FrameWork frame shared_ptr resourceManager = [(EAGLView*)self.view resourceManager]; m_framework = new framework_t(windowHandle); m_framework->Init(m_storage); + m_StickyThreshold = 10; m_locationController = [[UserLocationController alloc] initWithDelegate:self]; @@ -79,10 +80,9 @@ typedef FrameWork frame return self; } -- (void) OnHeading: (double) heading - withTimestamp: (NSDate *)timestamp +- (void) OnHeading: (CLHeading*) newHeading { - m_framework->SetHeading(heading); + m_framework->SetHeading(newHeading.trueHeading, newHeading.magneticHeading, newHeading.headingAccuracy); } - (void) OnLocation: (m2::PointD const &) mercatorPoint @@ -126,8 +126,9 @@ typedef FrameWork frame { CGPoint pt1 = [[[allTouches allObjects] objectAtIndex:0] locationInView:nil]; CGPoint pt2 = [[[allTouches allObjects] objectAtIndex:1] locationInView:nil]; + m_Pt1 = m2::PointD(pt1.x * self.view.contentScaleFactor, pt1.y * self.view.contentScaleFactor); - m_Pt2 = m2::PointD(pt2.x * self.view.contentScaleFactor, pt2.y * self.view.contentScaleFactor); + m_Pt2 = m2::PointD(pt2.x * self.view.contentScaleFactor, pt2.y * self.view.contentScaleFactor); } } @@ -162,18 +163,34 @@ typedef FrameWork frame m_framework->StartScale(ScaleEvent(m_Pt1.x, m_Pt1.y, m_Pt2.x, m_Pt2.y)); m_CurrentAction = SCALING; } + + m_isSticking = true; } - (void)touchesMoved:(NSSet*)touches withEvent:(UIEvent*)event { + m2::PointD TempPt1 = m_Pt1; + m2::PointD TempPt2 = m_Pt2; + [self updatePointsFromEvent:event]; bool needRedraw = false; + + if (m_isSticking) + { + if ((TempPt1.Length(m_Pt1) > m_StickyThreshold) || (TempPt2.Length(m_Pt2) > m_StickyThreshold)) + m_isSticking = false; + else + { + /// Still stickying. Restoring old points and return. + m_Pt1 = TempPt1; + m_Pt2 = TempPt2; + return; + } + } switch (m_CurrentAction) { - case NOTHING: - return; case DRAGGING: m_framework->DoDrag(DragEvent(m_Pt1.x, m_Pt1.y)); needRedraw = true; @@ -187,6 +204,8 @@ typedef FrameWork frame needRedraw = true; } break; + case NOTHING: + return; } } diff --git a/iphone/Maps/Classes/UserLocationController.hpp b/iphone/Maps/Classes/UserLocationController.hpp index 947785157b..a51c9542e5 100644 --- a/iphone/Maps/Classes/UserLocationController.hpp +++ b/iphone/Maps/Classes/UserLocationController.hpp @@ -9,8 +9,7 @@ - (void) OnLocation: (m2::PointD const &) mercatorPoint withConfidenceRadius: (double) confidenceRadius withTimestamp: (NSDate *) timestamp; -- (void) OnHeading: (double) heading - withTimestamp: (NSDate *) timestamp; +- (void) OnHeading: (CLHeading *)heading; - (void) OnLocationError: (NSString *) errorDescription; @end diff --git a/iphone/Maps/Classes/UserLocationController.mm b/iphone/Maps/Classes/UserLocationController.mm index 77d48fceb8..33cb15f944 100644 --- a/iphone/Maps/Classes/UserLocationController.mm +++ b/iphone/Maps/Classes/UserLocationController.mm @@ -38,7 +38,7 @@ [m_locationManager startUpdatingLocation]; if ([m_locationManager headingAvailable]) { - m_locationManager.headingFilter = 5; + m_locationManager.headingFilter = 1; [m_locationManager startUpdatingHeading]; } else @@ -55,8 +55,7 @@ - (void) locationManager: (CLLocationManager *) manager didUpdateHeading: (CLHeading *) newHeading { - double trueHeading = [newHeading trueHeading]; - [self.delegate OnHeading: trueHeading withTimestamp: newHeading.timestamp]; + [self.delegate OnHeading: newHeading]; } - (void) locationManager: (CLLocationManager *) manager diff --git a/iphone/Maps/Maps.xcodeproj/project.pbxproj b/iphone/Maps/Maps.xcodeproj/project.pbxproj index ff6a094816..225305f77b 100644 --- a/iphone/Maps/Maps.xcodeproj/project.pbxproj +++ b/iphone/Maps/Maps.xcodeproj/project.pbxproj @@ -525,7 +525,7 @@ buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; ARCHS = "$(ARCHS_STANDARD_32_BIT)"; - CODE_SIGN_IDENTITY = "iPhone Developer: Yury Melnichek (EDA9BLAEK7)"; + CODE_SIGN_IDENTITY = "iPhone Developer"; COMPRESS_PNG_FILES = NO; COPY_PHASE_STRIP = NO; CURRENT_PROJECT_VERSION = 1.0; @@ -553,7 +553,7 @@ OTHER_CFLAGS = "-Wall"; OTHER_CPLUSPLUSFLAGS = "$(OTHER_CFLAGS)"; PRODUCT_NAME = MapsWithMe; - PROVISIONING_PROFILE = "EC7DCB50-6434-4FA9-A1A4-7135151D0A58"; + PROVISIONING_PROFILE = ""; SDKROOT = iphoneos; STRIP_INSTALLED_PRODUCT = NO; VALID_ARCHS = armv6; diff --git a/map/drawer_yg.cpp b/map/drawer_yg.cpp index ee444002eb..4395f7774a 100644 --- a/map/drawer_yg.cpp +++ b/map/drawer_yg.cpp @@ -146,7 +146,7 @@ void DrawerYG::drawArea(vector const & pts, rule_ptr_t pRule, int de uint32_t const id = m_pSkin->mapColor(yg::Color::fromXRGB(pRule->GetFillColor(), pRule->GetAlpha())); ASSERT ( id != -1, () ); - m_pScreen->drawTriangles(&pts[0], pts.size()/*, res*/, id, depth); + m_pScreen->drawTrianglesList(&pts[0], pts.size()/*, res*/, id, depth); } uint8_t DrawerYG::get_font_size(rule_ptr_t pRule) @@ -274,7 +274,7 @@ void DrawerYG::Draw(di::DrawInfo const * pInfo, rule_ptr_t pRule, int depth) } } -void DrawerYG::drawStats(double duration, int scale, double lat, double lng, bool log2vis) +void DrawerYG::drawStats(double duration, int scale, double lat, double lng, m2::PointD const & pt, bool log2vis) { ostringstream out; out << "SPF: " << duration; @@ -282,9 +282,9 @@ void DrawerYG::drawStats(double duration, int scale, double lat, double lng, boo out << " FPS: inf"; else out << " FPS: " << 1.0 / duration; - m_pScreen->drawText(m2::PointD(10, 20), 0, 10, out.str().c_str(), yg::maxDepth, true, log2vis); + m_pScreen->drawText(pt + m2::PointD(10, 20), 0, 10, out.str().c_str(), yg::maxDepth, true, log2vis); out.str(""); out << "(" << lat << ", " << lng << ") Scale: " << scale; - m_pScreen->drawText(m2::PointD(10, 40), 0, 10, out.str().c_str(), yg::maxDepth, true, log2vis); + m_pScreen->drawText(pt + m2::PointD(10, 40), 0, 10, out.str().c_str(), yg::maxDepth, true, log2vis); } diff --git a/map/drawer_yg.hpp b/map/drawer_yg.hpp index 47ff0ec6a4..6856c6eed7 100644 --- a/map/drawer_yg.hpp +++ b/map/drawer_yg.hpp @@ -95,7 +95,7 @@ public: void onSize(int w, int h); - void drawStats(double duration, int scale, double lat, double lng, bool log2vis = false); + void drawStats(double duration, int scale, double lat, double lng, m2::PointD const & startPt = m2::PointD(0, 0), bool log2vis = false); shared_ptr screen() const; diff --git a/map/framework.hpp b/map/framework.hpp index 657c4dcfd7..fa14d95b20 100644 --- a/map/framework.hpp +++ b/map/framework.hpp @@ -36,6 +36,7 @@ #include "../base/start_mem_debug.hpp" +//#define DRAW_TOUCH_POINTS namespace di { class DrawInfo; } namespace drule { class BaseRule; } @@ -95,7 +96,9 @@ class FrameWork RenderQueue m_renderQueue; bool m_isHeadingEnabled; - double m_heading; + double m_trueHeading; + double m_magneticHeading; + double m_headingAccuracy; bool m_isPositionEnabled; m2::PointD m_position; @@ -104,6 +107,8 @@ class FrameWork /// is AddRedrawCommand enabled? bool m_isRedrawEnabled; + m2::PointD m_DebugPts[2]; + void Invalidate() { m_windowHandle->invalidate(); @@ -170,6 +175,8 @@ public: m_isPositionEnabled(false), m_isRedrawEnabled(true) { + m_DebugPts[0] = m2::PointD(0, 0); + m_DebugPts[1] = m2::PointD(0, 0); m_renderQueue.AddWindowHandle(m_windowHandle); } @@ -326,14 +333,31 @@ public: m2::PointD const center = m_navigator.Screen().ClipRect().Center(); +#ifdef DRAW_TOUCH_POINTS + + if (m_DebugPts[0] != m2::PointD(0, 0)) + { + pDrawer->screen()->drawArc(m_DebugPts[0], 0, math::pi * 2, 30, yg::Color(0, 0, 255, 32), yg::maxDepth); + pDrawer->screen()->fillSector(m_DebugPts[0], 0, math::pi * 2, 30, yg::Color(0, 0, 255, 32), yg::maxDepth); + } + + if (m_DebugPts[1] != m2::PointD(0, 0)) + { + pDrawer->screen()->drawArc(m_DebugPts[1], 0, math::pi * 2, 30, yg::Color(0, 0, 255, 64), yg::maxDepth); + pDrawer->screen()->fillSector(m_DebugPts[1], 0, math::pi * 2, 30, yg::Color(0, 0, 255, 32), yg::maxDepth); + } +#endif + DrawPosition(pDrawer); + pDrawer->drawStats(m_renderQueue.renderState().m_duration, GetCurrentScale(), + MercatorBounds::YToLat(center.y), MercatorBounds::XToLon(center.x), + ptShift); + + e->drawer()->screen()->endFrame(); + OGLCHECK(glPopMatrix()); - pDrawer->drawStats(m_renderQueue.renderState().m_duration, GetCurrentScale(), - MercatorBounds::YToLat(center.y), MercatorBounds::XToLon(center.x)); - - e->drawer()->screen()->endFrame(); } } @@ -344,67 +368,64 @@ public: m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(false); /// Drawing position and heading m2::PointD pxPosition = m_navigator.Screen().GtoP(m_position); - pDrawer->drawSymbol(pxPosition - ptShift, "current-position", yg::maxDepth); + pDrawer->drawSymbol(pxPosition, "current-position", yg::maxDepth); double pxConfidenceRadius = pxPosition.Length(m_navigator.Screen().GtoP(m_position + m2::PointD(m_confidenceRadius, 0))); - size_t sectorsCount = 360; - vector borderPts; - vector areaPts; - m2::PointD prevPt = pxPosition + m2::PointD(pxConfidenceRadius, 0) - ptShift; + pDrawer->screen()->drawArc(pxPosition, 0, math::pi * 2, pxConfidenceRadius, yg::Color(0, 0, 255, 64), yg::maxDepth - 2); + pDrawer->screen()->fillSector(pxPosition, 0, math::pi * 2, pxConfidenceRadius, yg::Color(0, 0, 255, 32), yg::maxDepth - 3); - for (size_t i = 0; i < sectorsCount; ++i) + if (m_isHeadingEnabled) { - m2::PointD curPt = pxPosition + m2::Rotate(m2::PointD(pxConfidenceRadius, 0), i / 180.0 * math::pi) - ptShift; - borderPts.push_back(curPt); - if (prevPt != curPt) - { - areaPts.push_back(pxPosition - ptShift); - areaPts.push_back(prevPt); - areaPts.push_back(curPt); - } - prevPt = curPt; + double trueHeadingRad = m_trueHeading / 180 * math::pi; + double magneticHeadingRad = m_magneticHeading / 180 * math::pi; + double headingAccuracyRad = m_headingAccuracy / 180 * math::pi; + + /// true heading + pDrawer->screen()->drawSector(pxPosition, + trueHeadingRad - headingAccuracyRad, + trueHeadingRad + headingAccuracyRad, + pxConfidenceRadius, + yg::Color(255, 0, 0, 64), + yg::maxDepth); + pDrawer->screen()->fillSector(pxPosition, + trueHeadingRad - headingAccuracyRad, + trueHeadingRad + headingAccuracyRad, + pxConfidenceRadius, + yg::Color(255, 0, 0, 32), + yg::maxDepth - 1); +/* /// magnetic heading + pDrawer->screen()->drawSector(pxPosition, + magneticHeadingRad - headingAccuracyRad, + magneticHeadingRad + headingAccuracyRad, + pxConfidenceRadius, + yg::Color(0, 255, 0, 64), + yg::maxDepth); + pDrawer->screen()->fillSector(pxPosition, + magneticHeadingRad - headingAccuracyRad, + magneticHeadingRad + headingAccuracyRad, + pxConfidenceRadius, + yg::Color(0, 255, 0, 32), + yg::maxDepth - 1); + */ } - - borderPts.push_back(pxPosition + m2::PointD(pxConfidenceRadius, 0) - ptShift); - areaPts.push_back(pxPosition - ptShift); - areaPts.push_back(prevPt); - areaPts.push_back(pxPosition + m2::PointD(pxConfidenceRadius, 0) - ptShift); - - pDrawer->screen()->drawPath( - &borderPts[0], - borderPts.size(), - pDrawer->screen()->skin()->mapPenInfo(yg::PenInfo(yg::Color(0, 0, 255, 64), 4, 0, 0, 0)), - yg::maxDepth - 1 - ); - - pDrawer->screen()->drawTriangles( - &areaPts[0], - areaPts.size(), - pDrawer->screen()->skin()->mapColor(yg::Color(0, 0, 255, 32)), - yg::maxDepth - 2); - -/* if (m_isHeadingEnabled) - { - LOG(LINFO, ("Drawing Heading", m_heading)); - m2::PointD v(0, 1); - v.Rotate(m_heading / 180 * math::pi); - m2::PointD pts[2] = {m_navigator.Screen().GtoP(m_position), - m_navigator.Screen().GtoP(m_position + v)}; - - - - pDrawer->screen()->drawPath( - pts, - 2, - pDrawer->screen()->skin()->mapPenInfo(yg::PenInfo(yg::Color(255, 0, 0, 255), 4, 0, 0, 0)), - yg::maxDepth - ); - } -*/ } } + void DrawScaleLiner(DrawerYG * pDrawer) + { + /// Compute Scaler + /// scaler should be between minPixSize and maxPixSize + int minPixSize = 40; + int maxPixSize = 80; + + m2::PointD lowerBoundPt = m2::PointD(0, m_renderQueue.renderState().m_surfaceHeight) + + m_renderQueue.renderState().coordSystemShift(); + + double minMetersSize = m_navigator.Screen().PtoG(lowerBoundPt + m2::PointD(minPixSize, 0)).x; + double maxMetersSize = m_navigator.Screen().PtoG(lowerBoundPt + m2::PointD(maxPixSize, 0)).x; + } + void DisableMyPositionAndHeading() { m_isPositionEnabled = false; @@ -429,10 +450,12 @@ public: UpdateNow(); } - void SetHeading(double heading) + void SetHeading(double trueHeading, double magneticHeading, double accuracy) { m_isHeadingEnabled = true; - m_heading = heading; + m_trueHeading = trueHeading; + m_magneticHeading = magneticHeading; + m_headingAccuracy = accuracy; UpdateNow(); } @@ -468,26 +491,44 @@ public: void StartDrag(DragEvent const & e) { m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); - m_navigator.StartDrag(m_navigator.OrientPoint(e.Pos() + ptShift), + m2::PointD pos = m_navigator.OrientPoint(e.Pos()) + ptShift; + m_navigator.StartDrag(pos, GetPlatform().TimeInSec()); + +#ifdef DRAW_TOUCH_POINTS + m_DebugPts[0] = pos; +#endif + Invalidate(); } void DoDrag(DragEvent const & e) { m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); - m_navigator.DoDrag(m_navigator.OrientPoint(e.Pos() + ptShift), + m2::PointD pos = m_navigator.OrientPoint(e.Pos()) + ptShift; + m_navigator.DoDrag(pos, GetPlatform().TimeInSec()); + +#ifdef DRAW_TOUCH_POINTS + m_DebugPts[0] = pos; +#endif + Invalidate(); } void StopDrag(DragEvent const & e) { m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); - m_navigator.StopDrag(m_navigator.OrientPoint(e.Pos() + ptShift), + m2::PointD pos = m_navigator.OrientPoint(e.Pos()) + ptShift; + + m_navigator.StopDrag(pos, GetPlatform().TimeInSec(), true); +#ifdef DRAW_TOUCH_POINTS + m_DebugPts[0] = m2::PointD(0, 0); +#endif + UpdateNow(); } @@ -503,7 +544,10 @@ public: void ScaleToPoint(ScaleToPointEvent const & e) { m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); - m_navigator.ScaleToPoint(m_navigator.OrientPoint(e.Pt() + ptShift), + + m2::PointD pt = m_navigator.OrientPoint(e.Pt()) + ptShift; + + m_navigator.ScaleToPoint(pt, e.ScaleFactor(), GetPlatform().TimeInSec()); @@ -525,27 +569,47 @@ public: { m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); - m_navigator.StartScale(m_navigator.OrientPoint(e.Pt1() + ptShift), - m_navigator.OrientPoint(e.Pt2() + ptShift), - GetPlatform().TimeInSec()); + m2::PointD pt1 = m_navigator.OrientPoint(e.Pt1()) + ptShift; + m2::PointD pt2 = m_navigator.OrientPoint(e.Pt2()) + ptShift; + + m_navigator.StartScale(pt1, pt2, GetPlatform().TimeInSec()); + +#ifdef DRAW_TOUCH_POINTS + m_DebugPts[0] = pt1; + m_DebugPts[1] = pt2; +#endif + Invalidate(); } void DoScale(ScaleEvent const & e) { m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); - m_navigator.DoScale(m_navigator.OrientPoint(e.Pt1() + ptShift), - m_navigator.OrientPoint(e.Pt2() + ptShift), - GetPlatform().TimeInSec()); + m2::PointD pt1 = m_navigator.OrientPoint(e.Pt1()) + ptShift; + m2::PointD pt2 = m_navigator.OrientPoint(e.Pt2()) + ptShift; + + m_navigator.DoScale(pt1, pt2, GetPlatform().TimeInSec()); + +#ifdef DRAW_TOUCH_POINTS + m_DebugPts[0] = pt1; + m_DebugPts[1] = pt2; +#endif + Invalidate(); } void StopScale(ScaleEvent const & e) { m2::PointD ptShift = m_renderQueue.renderState().coordSystemShift(true); - m_navigator.StopScale(m_navigator.OrientPoint(e.Pt1() + ptShift), - m_navigator.OrientPoint(e.Pt2() + ptShift), - GetPlatform().TimeInSec()); + m2::PointD pt1 = m_navigator.OrientPoint(e.Pt1()) + ptShift; + m2::PointD pt2 = m_navigator.OrientPoint(e.Pt2()) + ptShift; + + m_navigator.StopScale(pt1, pt2, GetPlatform().TimeInSec()); + +#ifdef DRAW_TOUCH_POINTS + m_DebugPts[0] = m2::PointD(0, 0); + m_DebugPts[1] = m2::PointD(0, 0); +#endif UpdateNow(); } diff --git a/qt/widgets.cpp b/qt/widgets.cpp index 375b161e17..4794bfe086 100644 --- a/qt/widgets.cpp +++ b/qt/widgets.cpp @@ -55,8 +55,8 @@ namespace qt p.m_resourceManager = m_resourceManager; p.m_isMultiSampled = false; p.m_frameBuffer = make_shared_ptr(new yg::gl::FrameBuffer(true)); - p.m_dynamicPagesCount = 1; - p.m_textPagesCount = 0; + p.m_dynamicPagesCount = 2; + p.m_textPagesCount = 2; m_p = shared_ptr(new DrawerYG(GetPlatform().SkinName(), p)); } diff --git a/yg/geometry_batcher.cpp b/yg/geometry_batcher.cpp index c26996e219..8d973b33c6 100644 --- a/yg/geometry_batcher.cpp +++ b/yg/geometry_batcher.cpp @@ -392,10 +392,10 @@ namespace yg } } - void GeometryBatcher::drawTriangles(m2::PointD const * points, size_t pointsCount, uint32_t styleID, double depth) + void GeometryBatcher::drawTrianglesList(m2::PointD const * points, size_t pointsCount, uint32_t styleID, double depth) { ResourceStyle const * style = m_skin->fromID(styleID); - if (!hasRoom(pointsCount, (pointsCount - 2) * 3, style->m_pageID)) + if (!hasRoom(pointsCount, pointsCount, style->m_pageID)) flush(style->m_pageID); ASSERT_GREATER_OR_EQUAL(pointsCount, 2, ()); diff --git a/yg/geometry_batcher.hpp b/yg/geometry_batcher.hpp index c7f47d1de4..169363929f 100644 --- a/yg/geometry_batcher.hpp +++ b/yg/geometry_batcher.hpp @@ -117,10 +117,11 @@ namespace yg uint32_t styleID, double depth); - void drawTriangles(m2::PointD const * points, - size_t pointsCount, - uint32_t styleID, - double depth); + /// drawing triangles list. assuming that each 3 points compose a triangle + void drawTrianglesList(m2::PointD const * points, + size_t pointsCount, + uint32_t styleID, + double depth); private: template diff --git a/yg/screen.hpp b/yg/screen.hpp index 81adfd732a..38140a45e3 100644 --- a/yg/screen.hpp +++ b/yg/screen.hpp @@ -1,6 +1,6 @@ #pragma once -#include "text_renderer.hpp" +#include "shape_renderer.hpp" #include "../std/shared_ptr.hpp" namespace yg @@ -8,14 +8,14 @@ namespace yg class ResourceManager; namespace gl { - class Screen : public TextRenderer + class Screen : public ShapeRenderer { private: public: - typedef TextRenderer::Params Params; + typedef ShapeRenderer::Params Params; - Screen(Params const & params) : TextRenderer(params) + Screen(Params const & params) : ShapeRenderer(params) {} }; } diff --git a/yg/shape_renderer.cpp b/yg/shape_renderer.cpp new file mode 100644 index 0000000000..498150f8ed --- /dev/null +++ b/yg/shape_renderer.cpp @@ -0,0 +1,68 @@ +#include "../base/SRC_FIRST.hpp" +#include "shape_renderer.hpp" +#include "skin.hpp" + +namespace yg +{ + namespace gl + { + ShapeRenderer::ShapeRenderer(base_t::Params const & params) : base_t(params) + { + } + + void ShapeRenderer::drawArc(m2::PointD const & center, double startA, double endA, double r, yg::Color const & c, double depth) + { + vector pts; + approximateArc(center, startA, endA, r, pts); + vector ptsD; + copy(pts.begin(), pts.end(), back_inserter(ptsD)); + drawPath(&ptsD[0], ptsD.size(), skin()->mapPenInfo(yg::PenInfo(c, 3, 0, 0, 0)), depth); + } + + void ShapeRenderer::approximateArc(m2::PointF const & center, double startA, double endA, double r, vector & pts) + { + double sectorA = math::pi / 180.0; + unsigned sectorsCount = floor((endA - startA) / sectorA); + sectorA = (endA - startA) / sectorsCount; + + for (unsigned i = 0; i <= sectorsCount; ++i) + pts.push_back(m2::Shift(m2::Rotate(m2::PointD(r, 0), startA + i * sectorA), center)); + } + + void ShapeRenderer::drawSector(m2::PointD const & center, double startA, double endA, double r, yg::Color const & c, double depth) + { + vector pts; + + pts.push_back(center); + approximateArc(center, startA, endA, r, pts); + pts.push_back(center); + + vector ptsD; + copy(pts.begin(), pts.end(), back_inserter(ptsD)); + drawPath(&ptsD[0], ptsD.size(), skin()->mapPenInfo(yg::PenInfo(c, 2, 0, 0, 0)), depth); + } + + void ShapeRenderer::fillSector(m2::PointD const & center, double startA, double endA, double r, yg::Color const & c, double depth) + { + vector arcPts; + + arcPts.push_back(center); + approximateArc(center, startA, endA, r, arcPts); + + m2::PointF pt0 = arcPts[0]; + m2::PointF pt1 = arcPts[1]; + + vector sectorPts; + + for (size_t i = 2; i < arcPts.size(); ++i) + { + sectorPts.push_back(pt0); + sectorPts.push_back(pt1); + sectorPts.push_back(arcPts[i]); + pt1 = arcPts[i]; + } + + drawTrianglesList(§orPts[0], sectorPts.size(), skin()->mapColor(c), depth); + } + } +} diff --git a/yg/shape_renderer.hpp b/yg/shape_renderer.hpp new file mode 100644 index 0000000000..c89bd5bf21 --- /dev/null +++ b/yg/shape_renderer.hpp @@ -0,0 +1,23 @@ +#pragma once + +#include "text_renderer.hpp" + +namespace yg +{ + namespace gl + { + class ShapeRenderer : public TextRenderer + { + private: + typedef TextRenderer base_t; + public: + + ShapeRenderer(base_t::Params const & params); + + void approximateArc(m2::PointF const & center, double startA, double endA, double r, vector & pts); + void drawArc(m2::PointD const & center, double startA, double endA, double r, yg::Color const & c, double depth); + void drawSector(m2::PointD const & center, double startA, double endA, double r, yg::Color const & c, double depth); + void fillSector(m2::PointD const & center, double startA, double endA, double r, yg::Color const & c, double depth); + }; + } +} diff --git a/yg/text_renderer.cpp b/yg/text_renderer.cpp index 40d5832826..023a5ee86b 100644 --- a/yg/text_renderer.cpp +++ b/yg/text_renderer.cpp @@ -67,10 +67,15 @@ namespace yg } } + void TextRenderer::setClipRect(m2::RectI const & rect) + { + m_tree.ForEach(bind(&TextObj::Draw, _1, this)); + m_tree.Clear(); + base_t::setClipRect(rect); + } + void TextRenderer::endFrame() { - shared_ptr rt; - m_tree.ForEach(bind(&TextObj::Draw, _1, this)); m_tree.Clear(); diff --git a/yg/text_renderer.hpp b/yg/text_renderer.hpp index 33c6227e46..6fad4b4619 100644 --- a/yg/text_renderer.hpp +++ b/yg/text_renderer.hpp @@ -65,6 +65,8 @@ namespace yg bool isFixedFont = false, bool log2vis = false); + void setClipRect(m2::RectI const & rect); + void endFrame(); }; } diff --git a/yg/yg.pro b/yg/yg.pro index 2dc6e55164..c22a601673 100644 --- a/yg/yg.pro +++ b/yg/yg.pro @@ -57,7 +57,8 @@ SOURCES += \ geometry_batcher.cpp \ text_renderer.cpp \ layer_manager.cpp \ - path_renderer.cpp + path_renderer.cpp \ + shape_renderer.cpp HEADERS += \ internal/opengl.hpp \ @@ -102,7 +103,8 @@ HEADERS += \ layer_manager.hpp \ gpu_state.hpp \ defines.hpp \ - path_renderer.hpp + path_renderer.hpp \ + shape_renderer.hpp !iphonesimulator-g++42 { !iphonedevice-g++42 { diff --git a/yg/yg_tests/screengl_test.cpp b/yg/yg_tests/screengl_test.cpp index fa2e4bc271..ad6829bdc7 100644 --- a/yg/yg_tests/screengl_test.cpp +++ b/yg/yg_tests/screengl_test.cpp @@ -472,7 +472,7 @@ namespace // p->drawTriangles(ptsFan, 5, yg::TriangleFan, p->skin()->mapColor(yg::Color(0, 255, 0, 255))); m2::PointD ptsList[6] = {m2::PointD(20, 80), m2::PointD(50, 120), m2::PointD(80, 80), m2::PointD(110, 80), m2::PointD(140, 120), m2::PointD(80, 120)}; - p->drawTriangles(ptsList, 6, /*yg::TriangleList, */p->skin()->mapColor(yg::Color(0, 0, 255, 255)), 0); + p->drawTrianglesList(ptsList, 6, /*yg::TriangleList, */p->skin()->mapColor(yg::Color(0, 0, 255, 255)), 0); } }; @@ -507,9 +507,9 @@ namespace prevPt = nextPt; } - p->drawTriangles(&vertices[0], - vertices.size(), - p->skin()->mapColor(yg::Color(0, 0, 255, 255)), 0); + p->drawTrianglesList(&vertices[0], + vertices.size(), + p->skin()->mapColor(yg::Color(0, 0, 255, 255)), 0); } }; @@ -726,6 +726,16 @@ namespace } }; + struct TestDrawSector + { + public: + void DoDraw(shared_ptr p) + { + p->drawArc(m2::PointD(100, 100), 0, math::pi * 2, 30, yg::Color(0, 0, 255, 128), 12000); + p->fillSector(m2::PointD(100, 100), 0, math::pi * 2, 30, yg::Color(0, 0, 255, 64), 12000); + } + }; + struct TestDrawSGIConvex { tess::VectorDispatcher m_d; @@ -881,7 +891,8 @@ namespace // UNIT_TEST_GL(TestDrawPathJoin); // UNIT_TEST_GL(TestDrawPathSolid1PX); // UNIT_TEST_GL(TestDrawPathSolid2PX); - UNIT_TEST_GL(TestDrawPathSolid); +// UNIT_TEST_GL(TestDrawPathSolid); + UNIT_TEST_GL(TestDrawSector); // UNIT_TEST_GL(TestDrawPathSolidDiffWidth); // UNIT_TEST_GL(TestDrawPathSolidWithZ); // UNIT_TEST_GL(TestDrawPathSolidWithClipRect);