{
emit zoomLevelChanged(m_zoomLevel);
setViewLocation(QPointF(25.5000, 65.0000));
+ emit locationChanged(m_sceneCoordinate);
// // Fetch some map tiles for demo purposes
// for (int x=9351; x<=9354; x++) {
{
qDebug() << __PRETTY_FUNCTION__;
setLocation(convertLatLonToSceneCoordinate(latLonCoordinate));
+ emit locationChanged(m_sceneCoordinate);
}
QUrl MapEngine::buildURL(int zoomLevel, QPoint tileNumbers)
void MapEngine::mapImageReceived(const QUrl &url, const QPixmap &pixmap)
{
+ //qDebug() << __PRETTY_FUNCTION__;
+
if (mapTilesInScene.contains(url.toString())) {
int zoom = -1;
int x = -1;
mapTilesInScene.insert(url.toString(), mapTile);
m_mapScene->addMapTile(mapTile);
- }
+
+ removeStackedTiles(mapTile);
+
- qDebug() << "Tile count: " << m_mapScene->items().count();
++ //qDebug() << "Tile count: " << m_mapScene->items().count();
+ }
}
QGraphicsScene* MapEngine::scene()
return (1 << zoomLevel) - 1;
}
- QRect MapEngine::calculateGrid(QPointF sceneCoordinate)
+ QRect MapEngine::calculateGrid(QPoint sceneCoordinate)
{
QPoint tileCoordinate = convertSceneCoordinateToTileNumber(m_zoomLevel, sceneCoordinate);
-
int gridWidth = (m_viewSize.width()/TILE_SIZE_X + 1) + (GRID_PADDING*2);
int gridHeight = (m_viewSize.height()/TILE_SIZE_Y + 1) + (GRID_PADDING*2);
-
int topLeftX = tileCoordinate.x() - (gridWidth/2);
int topLeftY = tileCoordinate.y() - (gridHeight/2);
return QRect(topLeftX, topLeftY, gridWidth, gridHeight);
}
- void MapEngine::setLocation(QPointF sceneCoordinate)
+ void MapEngine::setLocation(QPoint sceneCoordinate)
{
++ //qDebug() << __PRETTY_FUNCTION__;
++
m_sceneCoordinate = sceneCoordinate;
- emit locationChanged(m_sceneCoordinate);
if (centerTileChanged(sceneCoordinate)) {
- calculateTileGrid(sceneCoordinate);
- removeTilesOutOfBounds();
+ calculateNewTiles(sceneCoordinate);
+ removeOldTiles();
}
}
- bool MapEngine::centerTileChanged(QPointF sceneCoordinate)
+ bool MapEngine::centerTileChanged(QPoint sceneCoordinate)
{
QPoint centerTile = convertSceneCoordinateToTileNumber(m_zoomLevel, sceneCoordinate);
QPoint temp = m_centerTile;
return (centerTile != temp);
}
- void MapEngine::calculateNewTiles(QPointF sceneCoordinate)
-void MapEngine::calculateTileGrid(QPoint sceneCoordinate)
++void MapEngine::calculateNewTiles(QPoint sceneCoordinate)
{
//qDebug() << __PRETTY_FUNCTION__;
}
}
-void MapEngine::removeTilesOutOfBounds()
+void MapEngine::removeOldTiles()
{
//qDebug() << __PRETTY_FUNCTION__;
- int zoomFactor = 1 << (MAX_MAP_ZOOM_LEVEL - m_zoomLevel);
-
- QPoint topLeft = convertTileNumberToSceneCoordinate(m_zoomLevel, viewGrid.topLeft());
- QPoint bottomRight = convertTileNumberToSceneCoordinate(m_zoomLevel, viewGrid.bottomRight() + QPoint(1, 1));
+ QPointF topLeft = convertTileNumberToSceneCoordinate(m_zoomLevel, viewGrid.topLeft());
+ QPointF bottomRight = convertTileNumberToSceneCoordinate(m_zoomLevel, viewGrid.bottomRight() + QPoint(1, 1));
qreal width = bottomRight.x() - topLeft.x();
qreal height = bottomRight.y() - topLeft.y();
}
}
}
+}
+
+void MapEngine::removeStackedTiles(MapTile *tile)
+{
+ QList<QGraphicsItem *> collidingItems = tile->collidingItems(Qt::IntersectsItemBoundingRect);
+
+ foreach (QGraphicsItem *item, collidingItems) {
+
+ QRectF itemSceneRect = item->mapRectToScene(item->boundingRect());
+ QList<QGraphicsItem *> stackedItems = m_mapScene->items(itemSceneRect, Qt::IntersectsItemBoundingRect);
+ foreach(QGraphicsItem *stackedItem, stackedItems) {
+ if (item != stackedItem) {
+ MapTile *tmp = dynamic_cast<MapTile *>(item);
+ m_mapScene->removeItem(tmp);
+ mapTilesInScene.remove(buildURL(tmp->zoomLevel(), tmp->tileNumber()).toString());
+ }
+ }
+ }
}
void MapEngine::viewResized(const QSize &size)
{
m_viewSize = size;
- //setLocation(m_sceneCoordinate);
- calculateNewTiles(m_sceneCoordinate);
+ setLocation(m_sceneCoordinate);
}
void MapEngine::zoomIn()
{
+ qDebug() << __PRETTY_FUNCTION__;
+
if (m_zoomLevel >= MAX_MAP_ZOOM_LEVEL)
return;
emit zoomLevelChanged(m_zoomLevel);
setZValues();
-
- /// @todo START FETCHING TILES
- calculateTileGrid(m_sceneCoordinate);
+ calculateNewTiles(m_sceneCoordinate);
+ removeOldTiles();
}
void MapEngine::zoomOut()
{
+ qDebug() << __PRETTY_FUNCTION__;
+
if (m_zoomLevel <= MIN_MAP_ZOOM_LEVEL)
return;
emit zoomLevelChanged(m_zoomLevel);
setZValues();
-
- /// @todo START FETCHING TILES
- calculateTileGrid(m_sceneCoordinate);
+ calculateNewTiles(m_sceneCoordinate);
+ removeOldTiles();
}
void MapEngine::setZValues()
* @param tileNumber x & y numbers of the tile
* @return QPoint MapScene coordinate
*/
--
static QPoint convertTileNumberToSceneCoordinate(int zoomLevel, QPoint tileNumber)
{
int pow = 1 << (MAX_MAP_ZOOM_LEVEL - zoomLevel);
return QPoint(x, y);
}
+ /**
+ * @brief Convert MapScene coordinate to tile x & y numbers.
+ *
+ * @param zoomLevel ZoomLevel
+ * @param sceneCoordinate MapScene coordinate
+ * @return QPoint tile x & y numbers
+ */
- static QPoint convertSceneCoordinateToTileNumber(int zoomLevel, QPointF sceneCoordinate)
+ static QPoint convertSceneCoordinateToTileNumber(int zoomLevel, QPoint sceneCoordinate)
{
int pow = 1 << (MAX_MAP_ZOOM_LEVEL - zoomLevel);
int x = static_cast<int>(sceneCoordinate.x() / (TILE_SIZE_X*pow));
void setViewLocation(QPointF latLonCoordinate);
/**
- * @brief Converts latitude and longitude to scene coordinates.
+ * @brief Convert latitude and longitude to scene coordinates.
*
* @param latLonCoordinate latitude and longitude values
* @return scene coordinate
*/
- static QPointF convertLatLonToSceneCoordinate(QPointF latLonCoordinate)
+ static QPoint convertLatLonToSceneCoordinate(QPointF latLonCoordinate)
{
/// @todo CREATE TEST CASE & CHECK CALCULATION
qDebug() << __PRETTY_FUNCTION__;
qreal y = static_cast<qreal>((1.0 - log(tan(latitude * M_PI / 180.0) + 1.0
/ cos(latitude * M_PI / 180.0)) / M_PI) / 2.0);
- return QPointF(x*z*TILE_SIZE_X, y*z*TILE_SIZE_Y);
+ return QPointF(x*z*TILE_SIZE_X, y*z*TILE_SIZE_Y).toPoint();
}
- QRect calculateGrid(QPoint sceneCoordinate);
-
- void removeTilesOutOfBounds();
-
- void calculateTileGrid(QPoint sceneCoordinate);
-
public slots:
/**
* @brief Slot for setting current view location
* Emits locationChanged signal.
* @param sceneCoordinate Scene coordinates for new position
*/
- void setLocation(QPointF sceneCoordinate);
+ void setLocation(QPoint sceneCoordinate);
void viewResized(const QSize &size);
QUrl buildURL(int zoomLevel, QPoint tileNumbers);
/**
- * @brief Parses given URL to zoom, x and y values. Parsed values are
+ * @brief Parse given URL to zoom, x and y values. Parsed values are
* placed in variables given as parameters.
*
* @param url url to parse
*/
void setZValues();
+ /**
+ * @brief Calculate maximum value for tile in this zoom level.
+ *
+ * @param zoomLevel zoom level
+ * @return int tile's maximum value
+ */
int tileMaxValue(int zoomLevel);
+ /**
+ * @brief Calculate grid of tile coordinates from current scene coordinate.
+ *
+ * Grid size is calculated from view size and scene's current center coordinate.
+ *
+ * @param sceneCoordinate scene's current center coordinate
+ * @return QRect grid of tile coordinates
+ */
- QRect calculateGrid(QPointF sceneCoordinate);
++ QRect calculateGrid(QPoint sceneCoordinate);
+
+ /**
+ * @brief Calculate new tiles to fetch.
+ *
+ * @param sceneCoordinate scene's center coordinate
+ */
- void calculateNewTiles(QPointF sceneCoordinate);
++ void calculateNewTiles(QPoint sceneCoordinate);
+
+ /**
+ * @brief Remove tiles which are out of view bounds.
+ */
+ void removeOldTiles();
+
+ /**
+ * @brief Remove tiles which are stacked.
+ *
+ * Iterate through tiles which are under this map tile and remove obscured
+ * tiles.
+ *
+ * @param tile new tile covering old tiles
+ */
+ void removeStackedTiles(MapTile *tile);
+
+ /**
+ * @brief Check if center tile has changed.
+ *
+ * @param sceneCoordinate scene's center coordinate
+ * @return bool true if center tile changed, false otherwise
+ */
- bool centerTileChanged(QPointF sceneCoordinate);
++ bool centerTileChanged(QPoint sceneCoordinate);
private slots:
/**
*
* @param sceneCoordinate New scene coordinates
*/
- void locationChanged(QPointF sceneCoordinate);
+ void locationChanged(QPoint sceneCoordinate);
/**
* @brief Signal for zoom level change
*/
void zoomLevelChanged(int newZoomLevel);
+ /**
+ * @brief Signal for image fetching.
+ *
+ * @param url image url
+ */
void fetchImage(const QUrl &url);
- /**
- * @brief Signal for centering to scene coordinate.
- *
- * @param sceneCoordinate center scene coordinate
- */
- void centerToSceneCoordinates(QPointF sceneCoordinate);
-
private:
- bool centerTileChanged(QPoint sceneCoordinate);
-
MapScene *m_mapScene; ///< Scene for map tiles
MapFetcher *m_mapFetcher; ///< Fetcher for map tiles
int m_zoomLevel; ///< Current zoom level
QHash<QString, MapTile *> mapTilesInScene; ///< List of map tiles in map scene
- QSize m_viewSize;
- QPoint m_sceneCoordinate;
- QQueue<QString> mapTilesInView;
- QPoint m_centerTile;
- QRect viewGrid;
+ QSize m_viewSize; ///< Current view size
- QPointF m_sceneCoordinate; ///< Current center coordinate
++ QPoint m_sceneCoordinate; ///< Current center coordinate
+ QPoint m_centerTile; ///< Current center tile
+ QRect viewGrid; ///< Current grid of tiles in view
};
#endif // MAPENGINE_H
return currentTransform.m11();
}
- //void MapView::scrollContentsBy (int dx, int dy)
- //{
- // qDebug() << __PRETTY_FUNCTION__ << "dx:" << dx << "dy:" << dy;
- //
- // QGraphicsView::scrollContentsBy(dx, dy);
- //}
-
- void MapView::mouseMoveEvent(QMouseEvent *event)
+ void MapView::scrollContentsBy (int dx, int dy)
{
- m_scenePosition += m_mousePosition - mapToScene(event->pos());
+ // qDebug() << __PRETTY_FUNCTION__;
- emit viewScrolled(m_scenePosition);
- //qDebug() << __PRETTY_FUNCTION__ << "m_scenePosition" << m_scenePosition;
+ QGraphicsView::scrollContentsBy(dx, dy);
- m_mousePosition = mapToScene(event->pos());
+ QPoint centerInScene = mapToScene(frameRect().center()).toPoint();
+ // qDebug() << __PRETTY_FUNCTION__ << "centerInScene:" << centerInScene;
+ emit viewScrolled(centerInScene);
}
- void MapView::mousePressEvent(QMouseEvent *event)
+ void MapView::centerToSceneCoordinates(QPoint sceneCoordinate)
{
- m_mousePosition = mapToScene(event->pos());
- m_scenePosition = mapToScene(width() / 2 - 1, height() / 2 - 1);
- }
-
-
- void MapView::centerToSceneCoordinates(QPointF sceneCoordinate)
- {
- //qDebug() << __PRETTY_FUNCTION__ << "sceneCoordinate" << sceneCoordinate;
+ // qDebug() << __PRETTY_FUNCTION__ << "sceneCoordinate" << sceneCoordinate;
centerOn(sceneCoordinate);
}
void MapView::resizeEvent(QResizeEvent *event)
{
-- qDebug() << "Resize event: " << event->size();
++ //qDebug() << "Resize event: " << event->size();
emit viewResized(event->size());
}
--- /dev/null
+ /*
+ Situare - A location system for Facebook
+ Copyright (C) 2010 Ixonos Plc. Authors:
+
+ Sami Rämö - sami.ramo@ixonos.com
+
+ Situare is free software; you can redistribute it and/or
+ modify it under the terms of the GNU General Public License
+ version 2 as published by the Free Software Foundation.
+
+ Situare is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with Situare; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+ USA.
+ */
+
+ #include <QtTest/QtTest>
+
+ #include "map/mapengine.h"
+
+ class TestMapEngine: public QObject
+ {
+ Q_OBJECT
+ private slots:
+ void convertTileNumberToSceneCoordinate();
+ // void setViewLocation();
+ void convertLatLonToSceneCoordinate_data();
+ void convertLatLonToSceneCoordinate();
- void calculateRect();
- void setLocation();
-// void removeTilesOutOfBounds();
- void calculateTileGrid();
- void convert();
++ void setLocationNewTilesCount();
++ void setLocationRemovedTilesCount();
++ void zoomOutRemovedTilesCount();
++ void zoomInRemovedTilesCount();
+ };
+
+ /**
+ * @brief Test converting tile numbers to scene coordinates
+ *
+ * Different zoom levels are also tested
+ */
+ void TestMapEngine::convertTileNumberToSceneCoordinate()
+ {
+ QCOMPARE(MapEngine::convertTileNumberToSceneCoordinate(18, QPoint(0,0)), QPoint(0,0));
+ QCOMPARE(MapEngine::convertTileNumberToSceneCoordinate(18, QPoint(1,2)), QPoint(256,512));
+ QCOMPARE(MapEngine::convertTileNumberToSceneCoordinate(16, QPoint(3,4)), QPoint(3072,4096));
+ }
+
+ /**
+ * @brief DUMMY TESTCASE!
+ *
+ * @todo Actual test should be added when there is something to be tested
+ */
+ //void TestMapEngine::setViewLocation()
+ //{
+ // MapEngine mapEngine;
+ // mapEngine.setViewLocation(QPointF(25.0000, 65.0000));
+ //}
+
+ /**
+ * @brief Test data for converting latitude and longitude coordinates to scene coordinates
+ */
+ void TestMapEngine::convertLatLonToSceneCoordinate_data()
+ {
+ QTest::addColumn<QPointF>("coordinate");
+ QTest::addColumn<QPointF>("result");
+
+ QTest::newRow("top left") << QPointF(-180, 85.0511) << QPointF(0, 0);
+ QTest::newRow("bottom right") << QPointF(180, -85.0511) << QPointF(67108863, 67108863);
+ }
+
+ /**
+ * @brief Test converting real world cordinates to scene coordinates
+ * @todo Implement
+ */
+ void TestMapEngine::convertLatLonToSceneCoordinate()
+ {
+ QFETCH(QPointF, coordinate);
+ QFETCH(QPointF, result);
+
+ QCOMPARE(MapEngine::convertLatLonToSceneCoordinate(coordinate), result);
+ }
+
-void TestMapEngine::calculateRect()
++void TestMapEngine::setLocationNewTilesCount()
+ {
- MapEngine engine;
++ MapEngine engine;
+ engine.viewResized(QSize(800, 480));
- engine.setZoomLevel(14);
-
- int zoomFactor = 1 << (MAX_MAP_ZOOM_LEVEL - engine.getZoomLevel());
-
- QRect grid1 = QRect(-1, 0, 6, 4);
- QCOMPARE(engine.calculateGrid(QPointF(550.23*zoomFactor, 550.23*zoomFactor)), grid1);
-
- QRect grid2 = QRect(-3, -2, 6, 4);
- QCOMPARE(engine.calculateGrid(QPointF(0.23*zoomFactor, 0.23*zoomFactor)), grid2);
-
- QRect grid3 = QRect(1017, 498, 6, 4);
- QCOMPARE(engine.calculateGrid(QPointF(1020*TILE_SIZE_X*zoomFactor, 500*TILE_SIZE_Y*zoomFactor)), grid3);
-
- engine.viewResized(QSize(1280, 1024));
-
- QRect grid4 = QRect(1016, 497, 8, 7);
- QCOMPARE(engine.calculateGrid(QPointF(1020*TILE_SIZE_X*zoomFactor, 500*TILE_SIZE_Y*zoomFactor)), grid4);
-}
-
-void TestMapEngine::setLocation()
-{
- MapEngine engine;
- engine.setZoomLevel(14);
- engine.viewResized(QSize(800, 480));
-
- int zoomFactor = 1 << (MAX_MAP_ZOOM_LEVEL - engine.getZoomLevel());
+
+ QSignalSpy fetchImageSpy(&engine, SIGNAL(fetchImage(QUrl)));
+ QTest::qWait(1000);
+ fetchImageSpy.clear();
+
- engine.setLocation(QPointF(1220.23*zoomFactor, 1220.23*zoomFactor));
++ engine.setLocation(QPointF(1220.23*16, 1220.23*16));
+ QTest::qWait(1000);
+ QCOMPARE(fetchImageSpy.count(), 6*4);
+ fetchImageSpy.clear();
+
+ //Move one tile right and one down = 9 new tiles
- engine.setLocation(QPointF((1220.23+TILE_SIZE_X)*zoomFactor, (1220.23+TILE_SIZE_Y)*zoomFactor));
++ engine.setLocation(QPointF((1220.23+TILE_SIZE_X)*16, (1220.23+TILE_SIZE_Y)*16));
+ QTest::qWait(1000);
+ QCOMPARE(fetchImageSpy.count(), 9);
+ fetchImageSpy.clear();
+ }
+
-void TestMapEngine::convert()
++void TestMapEngine::setLocationRemovedTilesCount()
+ {
- int zoomFactor = 1 << (MAX_MAP_ZOOM_LEVEL - 14);
++ MapEngine engine;
++ engine.viewResized(QSize(800, 480));
++
++ const int maxItemsCount = 30;
+
- QPoint tileNumber = QPoint(1020, 500);
- QPointF sceneCoordinate = QPointF(tileNumber.x()*TILE_SIZE_X*zoomFactor, tileNumber.y()*TILE_SIZE_Y*zoomFactor);
- QPoint tile = MapEngine::convertSceneCoordinateToTileNumber(14, sceneCoordinate);
++ engine.setLocation(QPointF(1220.23*16, 1220.23*16));
++ QTest::qWait(1000);
++ engine.setLocation(QPointF(2220.23*16, 2220.23*16));
++ QTest::qWait(1000);
++ QVERIFY(engine.scene()->items().count() <= maxItemsCount);
++
++ engine.setLocation(QPointF(520.23*16, 2220.23*16));
++ QTest::qWait(1000);
++ engine.setLocation(QPointF(2220.23*16, 520.23*16));
++ QTest::qWait(1000);
+
- QCOMPARE(tileNumber, tile);
++ QVERIFY(engine.scene()->items().count() <= maxItemsCount);
+ }
+
-void TestMapEngine::calculateTileGrid()
++void TestMapEngine::zoomInRemovedTilesCount()
+ {
+ MapEngine engine;
-
+ engine.viewResized(QSize(800, 480));
- engine.setZoomLevel(14);
+
- int zoomFactor = 1 << (MAX_MAP_ZOOM_LEVEL - engine.getZoomLevel());
++ const int maxItemsCount = 30;
++
++ engine.setLocation(QPointF(1220.23*16, 1220.23*16));
++ QTest::qWait(1000);
++ QTest::qWait(1000);
++ QVERIFY(engine.scene()->items().count() <= maxItemsCount);
+
- engine.calculateTileGrid(QPointF(1020*TILE_SIZE_X*zoomFactor, 500*TILE_SIZE_X*zoomFactor));
++ engine.setLocation(QPointF(520.23*16, 2220.23*16));
++ QTest::qWait(1000);
++ engine.setLocation(QPointF(2220.23*16, 520.23*16));
++ QTest::qWait(1000);
++
++ QVERIFY(engine.scene()->items().count() <= maxItemsCount);
+ }
+
-//void TestMapEngine::removeTilesOutOfBounds()
-//{
-// MapEngine engine;
-// engine.viewResized(QSize(800, 480));
-// engine.setZoomLevel(14);
-//
-// int zoomFactor = 1 << (MAX_ZOOM_LEVEL - engine.getZoomLevel());
-//
-// engine.setLocation(QPointF(1220.23*zoomFactor, 1220.23*zoomFactor));
-// qDebug() << "Scene items: " << engine.scene()->items().count();
-// QTest::qWait(1000);
-// //Move one tile right and one tile down
-// engine.setLocation(QPointF((1220.23+TILE_SIZE_X)*zoomFactor, (1220.23+TILE_SIZE_Y)*zoomFactor));
-// QCOMPARE(engine.scene()->items().count(), 15);
-//}
++void TestMapEngine::zoomOutRemovedTilesCount()
++{
++ MapEngine engine;
++ engine.viewResized(QSize(800, 480));
++
++ const int maxItemsCount = 30;
++
++ engine.setLocation(QPointF(1220.23*16, 1220.23*16));
++ QTest::qWait(1000);
++ engine.setLocation(QPointF(2220.23*16, 2220.23*16));
++ QTest::qWait(1000);
++ QVERIFY(engine.scene()->items().count() <= maxItemsCount);
++
++ engine.setLocation(QPointF(520.23*16, 2220.23*16));
++ QTest::qWait(1000);
++ engine.setLocation(QPointF(2220.23*16, 520.23*16));
++ QTest::qWait(1000);
++
++ QVERIFY(engine.scene()->items().count() <= maxItemsCount);
++}
+
+ QTEST_MAIN(TestMapEngine)
+ #include "testmapengine.moc"
--- /dev/null
+ # #####################################################################
+ # Automatically generated by qmake (2.01a) Fri Mar 26 15:09:16 2010
+ # #####################################################################
+ CONFIG += qtestlib
+ QT += network
+ TEMPLATE = app
+ TARGET =
+ DEPENDPATH += .
+ INCLUDEPATH += . \
+ ../../../src/
-#DEFINES += QT_NO_DEBUG_OUTPUT
++DEFINES += QT_NO_DEBUG_OUTPUT
+
+ # Input
+ SOURCES += testmapengine.cpp \
+ ../../../src/map/mapengine.cpp \
+ ../../../src/map/mapscene.cpp \
+ ../../../src/map/maptile.cpp \
+ ../../../src/map/mapview.cpp \
+ ../../../src/map/mapfetcher.cpp
+ HEADERS += ../../../src/map/mapengine.h \
+ ../../../src/map/mapscene.h \
+ ../../../src/map/maptile.h \
+ ../../../src/map/mapview.h \
+ ../../../src/map/mapfetcher.h \
+ ../../../src/common.h
+ RESOURCES +=
+
+ # use don't use OpenGL when building in scratchbox
+ !maemo5 {
+ QT += opengl
+ message(OpenGL built in)
+ message(Make sure you have OpenGL development headers installed)
+ message(install headers with: sudo apt-get install libgl-dev libglu-dev)
+ }