source: geovis/trunk/Renderer.h @ 4628

Last change on this file since 4628 was 4628, checked in by ldelgass, 10 years ago

Add some Makefile flags for sleep throttling settings

File size: 12.2 KB
Line 
1/* -*- mode: c++; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2/*
3 * Copyright (C) 2004-2013  HUBzero Foundation, LLC
4 *
5 * Author: Leif Delgass <ldelgass@purdue.edu>
6 */
7
8#ifndef GEOVIS_RENDERER_H
9#define GEOVIS_RENDERER_H
10
11#include <string>
12#include <vector>
13#include <tr1/unordered_map>
14#include <typeinfo>
15
16#include <osg/ref_ptr>
17#include <osg/Node>
18#include <osg/Image>
19#include <osg/TransferFunction>
20#include <osgViewer/Viewer>
21#include <osgGA/StateSetManipulator>
22
23#include <osgEarth/StringUtils>
24#include <osgEarth/Map>
25#include <osgEarth/Viewpoint>
26#include <osgEarth/ImageLayer>
27#include <osgEarth/ElevationLayer>
28#include <osgEarth/ModelLayer>
29#include <osgEarth/TileSource>
30#include <osgEarth/ModelSource>
31#include <osgEarth/GeoData>
32#include <osgEarthUtil/EarthManipulator>
33#include <osgEarthUtil/MouseCoordsTool>
34#include <osgEarthUtil/Controls>
35#include <osgEarthUtil/Formatter>
36#include <osgEarthUtil/MGRSFormatter>
37#include <osgEarthUtil/AutoClipPlaneHandler>
38#include <osgEarthUtil/VerticalScale>
39
40#include "Types.h"
41#include "Trace.h"
42#include "MouseCoordsTool.h"
43#include "ScaleBar.h"
44
45// Controls if TGA format is sent to client
46//#define RENDER_TARGA
47#define TARGA_BYTES_PER_PIXEL 3
48
49namespace GeoVis {
50
51class ScreenCaptureCallback : public osg::Camera::DrawCallback
52{
53public:
54    ScreenCaptureCallback(osg::Texture2D *texture = NULL) :
55        osg::Camera::DrawCallback(),
56        _texture(texture)
57    {
58        _image = new osg::Image;
59    }
60
61    virtual void operator()(osg::RenderInfo &renderInfo) const
62    {
63        TRACE("Enter ScreenCaptureCallback");
64        int width, height;
65        if (renderInfo.getCurrentCamera() == NULL) {
66            ERROR("No camera");
67            return;
68        }
69        if (renderInfo.getCurrentCamera()->getViewport() == NULL) {
70            ERROR("No viewport");
71            return;
72        }
73        width = (int)renderInfo.getCurrentCamera()->getViewport()->width();
74        height = (int)renderInfo.getCurrentCamera()->getViewport()->height();
75        TRACE("readPixels: %d x %d", width, height);
76#if 0 //USE_OFFSCREEN_FRAMEBUFFER
77        _image = _texture->getImage();
78#else
79#ifdef RENDER_TARGA
80        _image->readPixels(0, 0, width, height,
81                           GL_BGR, GL_UNSIGNED_BYTE);
82#else
83        _image->readPixels(0, 0, width, height,
84                           GL_RGB, GL_UNSIGNED_BYTE);
85#endif
86#endif
87    }
88
89    osg::Image *getImage()
90    {
91        return _image.get();
92    }
93
94    osg::Texture2D *getTexture()
95    {
96        return _texture.get();
97    }
98
99private:
100    osg::ref_ptr<osg::Texture2D> _texture;
101    osg::ref_ptr<osg::Image> _image;
102};
103
104/**
105 * \brief GIS Renderer
106 */
107class Renderer
108{
109public:
110    typedef std::string ColorMapId;
111    typedef std::string ViewpointId;
112
113    enum GraticuleType {
114        GRATICULE_UTM,
115        GRATICULE_MGRS,
116        GRATICULE_GEODETIC
117    };
118
119    enum CoordinateDisplayType {
120        COORDS_LATLONG_DECIMAL_DEGREES,
121        COORDS_LATLONG_DEGREES_DECIMAL_MINUTES,
122        COORDS_LATLONG_DEGREES_MINUTES_SECONDS,
123        COORDS_MGRS
124    };
125
126    Renderer();
127    virtual ~Renderer();
128
129    // Colormaps
130
131    void addColorMap(const ColorMapId& id, osg::TransferFunction1D *xfer);
132
133    void deleteColorMap(const ColorMapId& id);
134
135    void setColorMapNumberOfTableEntries(const ColorMapId& id, int numEntries);
136
137    // Scene
138
139    void loadEarthFile(const char *path);
140
141    void resetMap(osgEarth::MapOptions::CoordinateSystemType type,
142                  const char *profile = NULL,
143                  double bounds[4] = NULL);
144
145    void clearMap();
146
147    // Map options
148
149    void setCoordinateReadout(bool state,
150                              CoordinateDisplayType type = COORDS_LATLONG_DECIMAL_DEGREES,
151                              int precision = -1);
152
153    void setReadout(int mouseX, int mouseY);
154
155    void clearReadout();
156
157    void setScaleBar(bool state);
158
159    void setScaleBarUnits(ScaleBarUnits units);
160
161    void setGraticule(bool enable, GraticuleType type = GRATICULE_GEODETIC);
162
163    void setViewerLightType(osg::View::LightingMode mode);
164
165    void setLighting(bool state);
166
167    void setTerrainLighting(bool state);
168
169    void setTerrainVerticalScale(double scale);
170
171    void setTerrainWireframe(bool state);
172
173    // Image raster layers
174
175    int getNumImageLayers() const
176    {
177        return (_map.valid() ? _map->getNumImageLayers() : 0);
178    }
179
180    void getImageLayerNames(std::vector<std::string>& names)
181    {
182        if (_map.valid()) {
183            osgEarth::ImageLayerVector layerVector;
184            _map->getImageLayers(layerVector);
185            osgEarth::ImageLayerVector::const_iterator itr;
186            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
187                //osgEarth::UID uid = (*itr)->getUID();
188                names.push_back((*itr)->getName());
189            }
190        }
191    }
192
193    bool addImageLayer(const char *name, osgEarth::TileSourceOptions& opts,
194                       bool makeShared = false, bool visible = true);
195
196    void removeImageLayer(const char *name);
197
198    void moveImageLayer(const char *name, unsigned int pos);
199
200    void setImageLayerOpacity(const char *name, double opacity);
201
202    void setImageLayerVisibility(const char *name, bool state);
203
204    void addColorFilter(const char *name, const char *shader);
205
206    void removeColorFilter(const char *name, int idx = -1);
207
208    // Elevation raster layers
209
210    int getNumElevationLayers() const
211    {
212        return (_map.valid() ? _map->getNumElevationLayers() : 0);
213    }
214
215    void getElevationLayerNames(std::vector<std::string>& names)
216    {
217        if (_map.valid()) {
218            osgEarth::ElevationLayerVector layerVector;
219            _map->getElevationLayers(layerVector);
220            osgEarth::ElevationLayerVector::const_iterator itr;
221            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
222                //osgEarth::UID uid = (*itr)->getUID();
223                names.push_back((*itr)->getName());
224            }
225        }
226    }
227
228    void addElevationLayer(const char *name, osgEarth::TileSourceOptions& opts);
229
230    void removeElevationLayer(const char *name);
231
232    void moveElevationLayer(const char *name, unsigned int pos);
233
234    void setElevationLayerVisibility(const char *name, bool state);
235
236    // Model layers
237
238    int getNumModelLayers() const
239    {
240        return (_map.valid() ? _map->getNumModelLayers() : 0);
241    }
242
243    void getModelLayerNames(std::vector<std::string>& names)
244    {
245        if (_map.valid()) {
246            osgEarth::ModelLayerVector layerVector;
247            _map->getModelLayers(layerVector);
248            osgEarth::ModelLayerVector::const_iterator itr;
249            for (itr = layerVector.begin(); itr != layerVector.end(); ++itr) {
250                //osgEarth::UID uid = (*itr)->getUID();
251                names.push_back((*itr)->getName());
252            }
253        }
254    }
255
256    void addModelLayer(const char *name, osgEarth::ModelSourceOptions& opts);
257
258    void removeModelLayer(const char *name);
259
260    void moveModelLayer(const char *name, unsigned int pos);
261
262    void setModelLayerOpacity(const char *name, double opacity);
263
264    void setModelLayerVisibility(const char *name, bool state);
265
266    // Render window
267
268    void setWindowSize(int width, int height);
269
270    int getWindowWidth() const
271    {
272        return _windowWidth;
273    }
274
275    int getWindowHeight() const
276    {
277        return _windowHeight;
278    }
279
280    // Camera
281
282    void saveNamedViewpoint(const char *name);
283
284    bool restoreNamedViewpoint(const char *name, double durationSecs);
285
286    bool removeNamedViewpoint(const char *name);
287
288    osgEarth::Viewpoint getViewpoint();
289
290    void setViewpoint(const osgEarth::Viewpoint& v, double durationSecs = 0.0);
291
292    void resetCamera(bool resetOrientation = true);
293
294    void setCameraOrientation(const double quat[4], bool absolute = true);
295
296    void panCamera(double x, double y);
297
298    void rotateCamera(double x, double y);
299
300    void zoomCamera(double z);
301
302    void setCameraDistance(double dist);
303
304    // Keyboard events
305
306    void keyPress(int key);
307
308    void keyRelease(int key);
309
310    // Mouse events
311
312    void setThrowingEnabled(bool state);
313
314    void mouseClick(int button, double x, double y);
315
316    void mouseDoubleClick(int button, double x, double y);
317
318    void mouseDrag(int button, double x, double y);
319
320    void mouseRelease(int button, double x, double y);
321
322    void mouseMotion(double x, double y);
323
324    void mouseScroll(int direction);
325
326    // Rendering an image
327
328    void setBackgroundColor(float color[3]);
329
330    void eventuallyRender();
331
332    bool render();
333
334    osg::Image *getRenderedFrame();
335
336    bool mapMouseCoords(float mouseX, float mouseY,
337                        osgEarth::GeoPoint &pt, bool invertY = true);
338
339    double computeMapScale();
340
341    const osgEarth::SpatialReference *getMapSRS()
342    {
343        if (_mapNode.valid()) {
344            return _mapNode->getMapSRS();
345        } else {
346            return NULL;
347        }
348    }
349
350    bool getMousePoint(double *x, double *y, double *z)
351    {
352        return (_coordsCallback.valid() && _coordsCallback->report(x, y, z));
353    }
354
355    bool getWorldCoords(const osgEarth::GeoPoint& mapPt, osg::Vec3d *world);
356
357    bool worldToScreen(const osg::Vec3d& world, osg::Vec3d *screen,
358                       bool invertY = true);
359
360    void setMaximumFrameRateInHertz(double rate)
361    {
362        if (rate > 60.0)
363            rate = 60.0;
364        if (rate < 0.25)
365            rate = 0.25;
366        _minFrameTime = 1.0/rate;
367    }
368
369    void setMaximumBitrate(double bitsPerSecond)
370    {
371        unsigned long bitsPerFrame = (_windowWidth * _windowHeight * 3 + 16) * 8;
372        double fps = bitsPerSecond / ((double)bitsPerFrame);
373        setMaximumFrameRateInHertz(fps);
374    }
375
376    double getMaximumFrameRateInHertz()
377    {
378        return (1.0/_minFrameTime);
379    }
380
381    double getMaximumBitrate()
382    {
383        unsigned long bitsPerFrame = (_windowWidth * _windowHeight * 3 + 16) * 8;
384        return ((double)bitsPerFrame * getMaximumFrameRateInHertz());
385    }
386
387    void markFrameStart();
388
389    void markFrameEnd();
390
391    long getTimeout();
392
393    void mapNodeUpdate();
394
395    std::string getCanonicalPath(const std::string& url) const;
396
397private:
398    typedef std::tr1::unordered_map<ColorMapId, osg::ref_ptr<osg::TransferFunction1D> > ColorMapHashmap;
399    typedef std::tr1::unordered_map<ViewpointId, osgEarth::Viewpoint> ViewpointHashmap;
400
401    void setupCache();
402
403    void initViewer();
404
405    void finalizeViewer();
406   
407    void initControls();
408
409    void initEarthManipulator();
410
411    void initMouseCoordsTool(CoordinateDisplayType type = COORDS_LATLONG_DECIMAL_DEGREES,
412                             int precision = -1);
413
414    osgEarth::Util::MGRSFormatter::Precision getMGRSPrecision(int precisionInMeters);
415
416    void initColorMaps();
417
418    void initCamera();
419
420    bool isPagerIdle();
421
422    bool checkNeedToDoFrame();
423
424    osgGA::EventQueue *getEventQueue();
425
426    bool _needsRedraw;
427    int _windowWidth, _windowHeight;
428    float _bgColor[3];
429
430    double _minFrameTime;
431    double _lastFrameTime;
432    osg::Timer_t _startFrameTime;
433
434    ColorMapHashmap _colorMaps;
435
436    std::string _baseURI;
437    std::string _cacheDir;
438
439    osg::ref_ptr<osg::Group> _sceneRoot;
440    osg::ref_ptr<osg::Group> _graticule;
441    osg::ref_ptr<osgEarth::MapNode> _mapNode;
442    osg::ref_ptr<osgEarth::Map> _map;
443    osg::ref_ptr<osgViewer::Viewer> _viewer;
444    osg::ref_ptr<ScreenCaptureCallback> _captureCallback;
445    osg::ref_ptr<osgEarth::Util::AutoClipPlaneCullCallback> _clipPlaneCullCallback;
446    osg::ref_ptr<MouseCoordsTool> _mouseCoordsTool;
447    osg::ref_ptr<MouseCoordsCallback> _coordsCallback;
448    osg::ref_ptr<osgEarth::Util::Controls::HBox> _hbox;
449    osg::ref_ptr<osgEarth::Util::Controls::LabelControl> _copyrightLabel;
450    osg::ref_ptr<osgEarth::Util::Controls::LabelControl> _scaleLabel;
451    osg::ref_ptr<osgEarth::Util::Controls::Frame> _scaleBar;
452    ScaleBarUnits _scaleBarUnits;
453    osg::ref_ptr<osgEarth::Util::EarthManipulator> _manipulator;
454    osg::ref_ptr<osgGA::StateSetManipulator> _stateManip;
455    osg::ref_ptr<osgEarth::Util::VerticalScale> _verticalScale;
456    ViewpointHashmap _viewpoints;
457};
458
459class MapNodeCallback : public osg::NodeCallback
460{
461public:
462    MapNodeCallback(Renderer *renderer) :
463        _renderer(renderer)
464    {}
465
466    virtual void operator()(osg::Node* node, osg::NodeVisitor* nv)
467    {
468        _renderer->mapNodeUpdate();
469        traverse(node, nv);
470    }
471private:
472    Renderer *_renderer;
473};
474
475}
476
477#endif
Note: See TracBrowser for help on using the repository browser.