From d441e6d475a76fdb4bdc5582dc398a057c7e716a Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sat, 18 Jun 2022 12:35:44 +0100 Subject: [PATCH 01/12] Add 3D spectrogram --- doc/img/MainWindow_graphics.png | Bin 0 -> 3873 bytes sdrbase/CMakeLists.txt | 2 + sdrbase/dsp/spectrumsettings.cpp | 9 + sdrbase/dsp/spectrumsettings.h | 12 + sdrbase/settings/mainsettings.h | 7 + sdrbase/settings/preferences.cpp | 4 + sdrbase/settings/preferences.h | 8 +- sdrbase/util/colormap.cpp | 5258 ++++++++++++++++++++++++++++ sdrbase/util/colormap.h | 62 + sdrgui/CMakeLists.txt | 5 + sdrgui/gui/glshadersimple.cpp | 24 +- sdrgui/gui/glshadersimple.h | 12 +- sdrgui/gui/glshaderspectrogram.cpp | 758 ++++ sdrgui/gui/glshaderspectrogram.h | 128 + sdrgui/gui/glshadertextured.cpp | 14 +- sdrgui/gui/glshadertextured.h | 6 +- sdrgui/gui/glspectrum.cpp | 671 +++- sdrgui/gui/glspectrum.h | 31 + sdrgui/gui/glspectrumgui.cpp | 45 + sdrgui/gui/glspectrumgui.h | 3 + sdrgui/gui/glspectrumgui.ui | 95 +- sdrgui/gui/graphicsdialog.cpp | 46 + sdrgui/gui/graphicsdialog.h | 43 + sdrgui/gui/graphicsdialog.ui | 128 + sdrgui/gui/spectrum.md | 36 + sdrgui/mainwindow.cpp | 10 + sdrgui/mainwindow.h | 1 + sdrgui/readme.md | 15 + sdrgui/resources/3dspectrogram.png | Bin 0 -> 1633 bytes sdrgui/resources/res.qrc | 1 + 30 files changed, 7364 insertions(+), 70 deletions(-) create mode 100644 doc/img/MainWindow_graphics.png create mode 100644 sdrbase/util/colormap.cpp create mode 100644 sdrbase/util/colormap.h create mode 100644 sdrgui/gui/glshaderspectrogram.cpp create mode 100644 sdrgui/gui/glshaderspectrogram.h create mode 100644 sdrgui/gui/graphicsdialog.cpp create mode 100644 sdrgui/gui/graphicsdialog.h create mode 100644 sdrgui/gui/graphicsdialog.ui create mode 100644 sdrgui/resources/3dspectrogram.png diff --git a/doc/img/MainWindow_graphics.png b/doc/img/MainWindow_graphics.png new file mode 100644 index 0000000000000000000000000000000000000000..5c1916e8c94058dc12511ee56cf5b38e4e2ccfe4 GIT binary patch literal 3873 zcmc&%cQhPKyVq+(3n7At8a2^t1c?^x>O%AqBt+ZQ*JrIxNYqVMStM9QL<>tqv{&y| zw?VMGYP8r@K6&qV&;8E%&bjCQcmJ4~XMQvDoSEl&e$UJ#0!{Ro7;Z3-k&!VO=sz?g zBO~Xyl>b3Taap5)-g}n~d7zn|HrdCao4Csk)iW()Ei$s2G{#eB>dQX8pZ=3TGP0{3 ze+qfe%QCl1p~2vxmPLreR^Cpa#Uyu6zn?3d6LckBn0-@#!pd@5RL?J?Dk0`u+iJdk{dU3CjK0JjyW)RGYE>gxy+LVc+<7{lE(Ck8UqVw;7 zk&&ir{&B&NikHj~|LtOlXG<5S2jMx@_HD>+x;vU89}3p5Mk*^4vtBwj2UL*`U+?qV z@1bES!&oeqH+bIvo!j<&Q;xK~8D$p*>FD^l;uST5%Pf!nm&SN^cgtw<64q*eyT`f> zeeY1Bre7HmO%6`Bg&7s9W{yq0lPRh*dE+rj%#LI|702dSZp zsXVSBN#QG-UFZ8b@tUL?vdIEZ!9B8Y*FJ=pKk*LTk?y0px|>b=LuyFj$vd}M>y6CR zZ<%U_+MLs;Au}q#uQe6>%79+`u4j?&b1ju$#`u7W1?FQR09Tr zMeTK(_J8%utQhU0h>cK4Iife2He&d=Af`HPmN@hKw282k`a^{F3%P5N)mMDw%MYKan4%>uDwQwhBX-A z(L98-)pfDPj%@QJl3#>f>@%U4?y=#+e7GFJVE*%w5JinB--Bf(@!4C3y&rF(sf_K3 z_3P|%sN@mw4LhFE)J^fL?0fyb|F97R3(ma?bm3j8&HJMmTM`}?X0dKH;#jw?)G?j= zTLrl@|DJKCVyzSkkclF7&m_-5qR838aMS6(Xr|xOEF11Z??l?D6t{oc8h9dVBLwp! z%t4K@X>cy|Yo8vKnpb$zYRvKGR?wq zP`fU}f1;!KIm~FUGpq34qcZNvj_)`?W3p^;o>KtTl@vnbky)p&+nj+32)S$qCDR&H z$dvN&@oB`LkMoyi+pG_+6crrDx4}H{kjM}2>vQF$!zB=f-6`yKZ%L?_RIIchn#$Dv z+(yK8A!@ankwWTzcv6j^No+3LHuWm;@SFl?E?~;zvH4-v3b{d8Vy+VnV{&IUDQRxD z1tl>yyqcu{n=Z?;J}+KeNehh9JjAst>0V5c43+_O($mzcOsvonr#?Ep8IBZO6~8|Q zKJ-hJJ(dVpR{=zqyvX$?3b?6i{X3)ogW?Gn8I%H@O!#<~;4*&gc_f6+Kb|Pi$@{+m zeVH@0&xR2y`#nNe5m$!v@+Q6jHGk42xeg&z>g($(tg5_kJNtuCwyOk9L zP!&{{TZm`$N{aYn-Tdw=3xgbb|19D&y}`p{S(C2(KUhL_!6PAVe7q2}&(qVhOsE$d z@vEfZ;H$te&uos>0+$}Fs;70uF0vzyjXeT@9JK>L^q!LTs&IROfE_j8^M!0AGV%x_ zD;-8H@XU4_JJ&^%W$NhIb~kS5{%}9I5#_)gv)@|)q0(ag!OV}>t4Rt$ltGXdM$boGD!lmXme>$_c>(9QdwAGQ(9FCxB^D|kR^$fkUn~mpV z%Yo*gd)G2!%0=4}_V6)jd$$INfAOh)w7$mQ)m@&Qk?g5CrEm|g+G)8phq97;d}3#J zos)qPZ|_JWQnZ_DhqT@+6g2jiZLT3;7S}>(?Y;m?y?DH6Py*Sy!z!i~1(` zZwR}2U)5<}TAIj^W>7IzHp+eZTY*-KY7fN{3y>0%-0G5?4sh_iqxMbG-RBy+2jVMW zQSso5t_%eWJQHner_YkZY5QOZ+G8u$&W+<>wCGOakl=)EYz!WOC2c+(Jx~mHs`{06 zb8>Pro|%7}o|5@gT>H{crI1b~@{{=Noo3EmzS9#^28c86?TD!rSDgC11Wb<48~}EP zXGy8m)hABvc*q|yfHEJdF|B=0O|@>dNk`vq1rhGg55O1>-)h0?O)JO2*V!#}MKVIC zU1%q2b-13xAXEB|UTm+^W%v|4qW60%Ag9ap4nG}vcbX=>7#`}ye&0=$sW684kzxgX zDaKY-^kywNYXTb;S*NC0bqd$kj1H^KVw_iiii>yKTjEwYc4_Twf2(z=Mn-LV$5LmR zT3a8dBYE*&$Aj4)Uo=#7H9pSz*`LF&8niKK?bs#p;wRJPDXSr!YJ8TfrIkPX%7=ig zq*uV)?ueDE9G~)exSGJ*QzF`J??$I3>M(L9F-sQ5p;R1%#B@F2SOL zBL`sunN+D6_2(IM@XI$L56%x`D7ZgEvdyIJBm8hOY|ZM%nOqrs+#kPQe3MvNEwt6y zEHt!}VRP+&RCQL8R}1Q7nGQUwc2+t(>v2?mi?-=Bq#+N;8;Mg@ow{SJR=@m%u->kG zN=n0L-lHB#E7$B77T0mQNO$+vp2#d4Duw>qv%g=a7d7L=bfNhr!3q88cEkK5s^x4a zh;D`iTwmpeELGUY$e9qtgo(~4{^f~6IL{aD;XFK>Hi^EorC84uA*()JUREeOhC872 zm){xoI994K`NNhB$OjRXSXBW(RWpk7NWo{k$k(?g>c5nqm`Tc(rOeLGk_=>(`SGH! zv5KC)_N*+(C@+~S+D(nii-LuauQ_HIW;j(@iiNmBfl$mo5~8nOmh$%PTax~tMe&_- zuH7kpeSIhtD%{}aW!hjiG03x)odBrFKA);gN@B>=S4gB3m9r}vlHkUd8fp1s_c_wU zgsvk71`}xiBcuI40Y;){K|al-s-f@}&C?PX58LTVH`?;M%0RwG_}Ty*&mSsonvOL- zpR+WN_A2I2ST7hJh$?#T+)q@nQ>>I4Y=AJaMeM^*NJ-LkZqX`dN94)gF&RuvZeNCD8 z#DWH>c|t2(k4s!59*n(tsV`@s$;8BzvHOT zZpB9z;BSPeQJ4nEbAspoQRX&hp}?Tf*#rh7gP^L)i=3(K8|n8TsoG6G$j5E&6IHXe zDE_6cqj^%oERCbAHDq>Q_v+dAorWz{#pP7KnOpH-`ZKY%Yk+re%?jh>GY)D4e)j1- zeS*n5{2a+k2x=_mvBeXB3oT>hXGR{*B?f1!+?f+ZkTLu%3R))>#dm1(m1QRyQc~lN z`S#cDH(!YlcbU96A83~0UNmw7U?AQ|Vgps|iF8>7y4dby(1;zrH7+fO0h?-?Ga(D= zjp6u9Jqx0(=IHN3Okb$!>n$FiC0MuF?f$(Pm#!pg-=KrA8OrCDqS|*GI6q+K1S%Sqvp<;2QGG4hjAQFSa^>+$ie=4ygN*G)o83u0>a z>y*@0p=+sp4*ZFC9_qX`AojY+GNWrKgwBUTEPT7;~{rdf|*!3bceKB;DmoU2UXux1I86W>x^mjS~9|y zHQH2s;%?RI+mPQF8)$>n(YVm1Zj1p&02bHx3=@wR)h7VwS_W0mef6cPB!P3|JE4LL z;flT6ABF@47ytTUr7{sZOPDL}nB6T=8e8~)j`h?Jym_X+kQo;)8icUaoK_2P%GSXJA2(Eeh&#~a9>be2&VN}?yUT_C30TAwsG?i}as$}2r4 zb%OUGF6f)O-{@t~j+Zy0QRU5!LI>GouRe|e5V@C`W+;ttJs1>u=*sx`>)# YWTzcDigs%*zqMork4zqZ)OLdY6H%|M_y7O^ literal 0 HcmV?d00001 diff --git a/sdrbase/CMakeLists.txt b/sdrbase/CMakeLists.txt index c34410632..8ebd6369f 100644 --- a/sdrbase/CMakeLists.txt +++ b/sdrbase/CMakeLists.txt @@ -172,6 +172,7 @@ set(sdrbase_SOURCES util/aprs.cpp util/astronomy.cpp util/azel.cpp + util/colormap.cpp util/coordinates.cpp util/crc.cpp util/CRC64.cpp @@ -383,6 +384,7 @@ set(sdrbase_HEADERS util/aprs.h util/astronomy.h util/azel.h + util/colormap.h util/coordinates.h util/CRC64.h util/csv.h diff --git a/sdrbase/dsp/spectrumsettings.cpp b/sdrbase/dsp/spectrumsettings.cpp index 713557e33..9b9116ecf 100644 --- a/sdrbase/dsp/spectrumsettings.cpp +++ b/sdrbase/dsp/spectrumsettings.cpp @@ -49,6 +49,7 @@ void SpectrumSettings::resetToDefaults() m_displayCurrent = true; m_displayWaterfall = true; m_invertedWaterfall = true; + m_display3DSpectrogram = false; m_displayMaxHold = false; m_displayHistogram = false; m_displayGrid = false; @@ -64,6 +65,8 @@ void SpectrumSettings::resetToDefaults() m_markersDisplay = MarkersDisplayNone; m_useCalibration = false; m_calibrationInterpMode = CalibInterpLinear; + m_3DSpectrogramStyle = Outline; + m_3DSpectrogramColorMap = "Angel"; } QByteArray SpectrumSettings::serialize() const @@ -99,6 +102,9 @@ QByteArray SpectrumSettings::serialize() const s.writeS32(28, (int) m_markersDisplay); s.writeBool(29, m_useCalibration); s.writeS32(30, (int) m_calibrationInterpMode); + s.writeBool(31, m_display3DSpectrogram); + s.writeS32(32, (int) m_3DSpectrogramStyle); + s.writeString(33, m_3DSpectrogramColorMap); s.writeS32(100, m_histogramMarkers.size()); for (int i = 0; i < m_histogramMarkers.size(); i++) { @@ -196,6 +202,9 @@ bool SpectrumSettings::deserialize(const QByteArray& data) d.readBool(29, &m_useCalibration, false); d.readS32(30, &tmp, 0); m_calibrationInterpMode = (CalibrationInterpolationMode) tmp; + d.readBool(31, &m_display3DSpectrogram, false); + d.readS32(32, (int*)&m_3DSpectrogramStyle, (int)Outline); + d.readString(33, &m_3DSpectrogramColorMap, "Angel"); int histogramMarkersSize; d.readS32(100, &histogramMarkersSize, 0); diff --git a/sdrbase/dsp/spectrumsettings.h b/sdrbase/dsp/spectrumsettings.h index 0d917848b..badb812b2 100644 --- a/sdrbase/dsp/spectrumsettings.h +++ b/sdrbase/dsp/spectrumsettings.h @@ -52,6 +52,15 @@ public: CalibInterpLog //!< log power (dB linear) }; + enum SpectrogramStyle + { + Points, + Lines, + Solid, + Outline, + Shaded + }; + int m_fftSize; int m_fftOverlap; FFTWindow::Function m_fftWindow; @@ -66,6 +75,7 @@ public: bool m_displayWaterfall; bool m_invertedWaterfall; Real m_waterfallShare; + bool m_display3DSpectrogram; bool m_displayMaxHold; bool m_displayCurrent; bool m_displayHistogram; @@ -86,6 +96,8 @@ public: QList m_calibrationPoints; bool m_useCalibration; CalibrationInterpolationMode m_calibrationInterpMode; //!< How is power interpolated between calibration points + SpectrogramStyle m_3DSpectrogramStyle; + QString m_3DSpectrogramColorMap; static const int m_log2FFTSizeMin = 6; // 64 static const int m_log2FFTSizeMax = 15; // 32k diff --git a/sdrbase/settings/mainsettings.h b/sdrbase/settings/mainsettings.h index d341dee3d..26af1c809 100644 --- a/sdrbase/settings/mainsettings.h +++ b/sdrbase/settings/mainsettings.h @@ -183,6 +183,13 @@ public: const AudioDeviceManager *getAudioDeviceManager() const { return m_audioDeviceManager; } void setAudioDeviceManager(AudioDeviceManager *audioDeviceManager) { m_audioDeviceManager = audioDeviceManager; } + int getMultisampling() const { return m_preferences.getMultisampling(); } + void setMultisampling(int samples) + { + m_preferences.setMultisampling(samples); + emit preferenceChanged(Preferences::Multisampling); + } + signals: void preferenceChanged(int); diff --git a/sdrbase/settings/preferences.cpp b/sdrbase/settings/preferences.cpp index 4137f196c..156074c93 100644 --- a/sdrbase/settings/preferences.cpp +++ b/sdrbase/settings/preferences.cpp @@ -21,6 +21,7 @@ void Preferences::resetToDefaults() m_logFileName = "sdrangel.log"; m_consoleMinLogLevel = QtDebugMsg; m_fileMinLogLevel = QtDebugMsg; + m_multisampling = 0; } QByteArray Preferences::serialize() const @@ -39,6 +40,7 @@ QByteArray Preferences::serialize() const s.writeString((int) StationName, m_stationName); s.writeFloat((int) Altitude, m_altitude); s.writeS32((int) SourceItemIndex, m_sourceItemIndex); + s.writeS32((int) Multisampling, m_multisampling); return s.final(); } @@ -92,6 +94,8 @@ bool Preferences::deserialize(const QByteArray& data) m_fileMinLogLevel = QtDebugMsg; } + d.readS32((int) Multisampling, &m_multisampling, 0); + return true; } else { diff --git a/sdrbase/settings/preferences.h b/sdrbase/settings/preferences.h index 2baf4c204..07356f78f 100644 --- a/sdrbase/settings/preferences.h +++ b/sdrbase/settings/preferences.h @@ -21,7 +21,8 @@ public: FileMinLogLevel, StationName, Altitude, - SourceItemIndex + SourceItemIndex, + Multisampling }; Preferences(); @@ -71,6 +72,9 @@ public: const QString& getLogFileName() const { return m_logFileName; } void setLogFileName(const QString& value) { m_logFileName = value; } + int getMultisampling() const { return m_multisampling; } + void setMultisampling(int samples) { m_multisampling = samples; } + protected: QString m_sourceDevice; //!< Identification of the source used in R0 tab (GUI flavor) at startup int m_sourceIndex; //!< Index of the source used in R0 tab (GUI flavor) at startup @@ -88,6 +92,8 @@ protected: QtMsgType m_fileMinLogLevel; bool m_useLogFile; QString m_logFileName; + + int m_multisampling; //!< Number of samples to use for multisampling anti-aliasing (typically 0 or 4) }; #endif // INCLUDE_PREFERENCES_H diff --git a/sdrbase/util/colormap.cpp b/sdrbase/util/colormap.cpp new file mode 100644 index 000000000..9f9c7e7ea --- /dev/null +++ b/sdrbase/util/colormap.cpp @@ -0,0 +1,5258 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2022 Jon Beniston, M7RCE // +// Copyright (C) 2021 Fabio Crameri // +// // +// Permission is hereby granted, free of charge, to any person obtaining a copy // +// of this software and associated documentation files (the "Software"), to deal // +// in the Software without restriction, including without limitation the rights // +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell // +// copies of the Software, and to permit persons to whom the Software is // +// furnished to do so, subject to the following conditions: // +// // +// The above copyright notice and this permission notice shall be included in // +// all copies or substantial portions of the Software. // +// // +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR // +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, // +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // +// SOFTWARE. // +/////////////////////////////////////////////////////////////////////////////////// + +#include "colormap.h" + +QStringList ColorMap::getColorMapNames() +{ + QStringList names = m_colorMaps.keys(); + names.sort(); + return names; +} + +const float *ColorMap::getColorMap(const QString &name) +{ + return m_colorMaps.value(name); +} + +QHash ColorMap::m_colorMaps{ + {"Angel", &m_angel[0]}, + {"Jet", &m_jet[0]}, + {"Turbo", &m_turbo[0]}, + {"Parula", &m_parula[0]}, + {"Hot", &m_hot[0]}, + {"Cool", &m_cool[0]}, + {"Batlow", &m_batlow[0]}, + {"Hawaii", &m_hawaii[0]}, + {"Acton", &m_acton[0]}, + {"Imola", &m_imola[0]}, + {"Tokyo", &m_tokyo[0]}, + {"Lapaz", &m_lapaz[0]}, + {"Buda", &m_buda[0]}, + {"Devon", &m_devon[0]}, + {"Lajolla", &m_lajolla[0]}, + {"Bamako", &m_bamako[0]}, + {"Plasma", &m_plasma[0]}, + {"Rainbow", &m_rainbow[0]}, + {"Prism", &m_prism[0]}, + {"Viridis", &m_viridis[0]}, +}; + +const float ColorMap::m_angel[m_size] = +{ + 0.0, 0.000976577, 0.0588235, + 0.0, 0.00209049, 0.0627451, + 0.0, 0.00332647, 0.0666667, + 0.0, 0.00469978, 0.0705882, + 0.0, 0.00621042, 0.0745098, + 0.0, 0.00784314, 0.0784314, + 0.0, 0.00961318, 0.0823529, + 0.0, 0.0115053, 0.0862745, + 0.0, 0.0135348, 0.0901961, + 0.0, 0.0156863, 0.0941176, + 0.0, 0.0179751, 0.0980392, + 0.0, 0.0203861, 0.101961, + 0.0, 0.0229343, 0.105882, + 0.0, 0.0256199, 0.109804, + 0.0, 0.0284276, 0.113725, + 0.0, 0.0313725, 0.117647, + 0.0, 0.0344396, 0.121569, + 0.0, 0.037644, 0.12549, + 0.0, 0.0409857, 0.129412, + 0.0, 0.0444495, 0.133333, + 0.0, 0.0480354, 0.137255, + 0.0, 0.0517586, 0.141176, + 0.0, 0.0556191, 0.145098, + 0.0, 0.0596017, 0.14902, + 0.0, 0.0637217, 0.152941, + 0.0, 0.0679789, 0.156863, + 0.0, 0.0723583, 0.160784, + 0.0, 0.0768597, 0.164706, + 0.0, 0.0814984, 0.168627, + 0.0, 0.0862745, 0.172549, + 0.0, 0.0911727, 0.176471, + 0.0, 0.0962081, 0.180392, + 0.0, 0.101366, 0.184314, + 0.0, 0.106661, 0.188235, + 0.0, 0.112093, 0.192157, + 0.0, 0.117647, 0.196078, + 0.0, 0.123339, 0.2, + 0.0, 0.129152, 0.203922, + 0.0, 0.135103, 0.207843, + 0.0, 0.141176, 0.211765, + 0.0, 0.147387, 0.215686, + 0.0, 0.153719, 0.219608, + 0.0, 0.160189, 0.223529, + 0.0, 0.166796, 0.227451, + 0.0, 0.173526, 0.231373, + 0.0, 0.180392, 0.235294, + 0.0, 0.187381, 0.239216, + 0.0, 0.194507, 0.243137, + 0.0, 0.20177, 0.247059, + 0.0, 0.209155, 0.25098, + 0.0, 0.216663, 0.254902, + 0.0, 0.224308, 0.258824, + 0.0, 0.23209, 0.262745, + 0.0, 0.239994, 0.266667, + 0.0, 0.248035, 0.270588, + 0.0, 0.256214, 0.27451, + 0.0, 0.264515, 0.278431, + 0.0, 0.272938, 0.282353, + 0.0, 0.281498, 0.286275, + 0.0, 0.290196, 0.290196, + 0.0, 0.294118, 0.28922, + 0.0, 0.298039, 0.288106, + 0.0, 0.301961, 0.28687, + 0.0, 0.305882, 0.285496, + 0.0, 0.309804, 0.283986, + 0.0, 0.313725, 0.282353, + 0.0, 0.317647, 0.280583, + 0.0, 0.321569, 0.278691, + 0.0, 0.32549, 0.276661, + 0.0, 0.329412, 0.27451, + 0.0, 0.333333, 0.272221, + 0.0, 0.337255, 0.26981, + 0.0, 0.341176, 0.267262, + 0.0, 0.345098, 0.264576, + 0.0, 0.34902, 0.261769, + 0.0, 0.352941, 0.258824, + 0.0, 0.356863, 0.255756, + 0.0, 0.360784, 0.252552, + 0.0, 0.364706, 0.24921, + 0.0, 0.368627, 0.245747, + 0.0, 0.372549, 0.242161, + 0.0, 0.376471, 0.238437, + 0.0, 0.380392, 0.234577, + 0.0, 0.384314, 0.230594, + 0.0, 0.388235, 0.226474, + 0.0, 0.392157, 0.222217, + 0.0, 0.396078, 0.217838, + 0.0, 0.4, 0.213336, + 0.0, 0.403922, 0.208698, + 0.0, 0.407843, 0.203922, + 0.0, 0.411765, 0.199023, + 0.0, 0.415686, 0.193988, + 0.0, 0.419608, 0.18883, + 0.0, 0.423529, 0.183536, + 0.0, 0.427451, 0.178103, + 0.0, 0.431373, 0.172549, + 0.0, 0.435294, 0.166857, + 0.0, 0.439216, 0.161044, + 0.0, 0.443137, 0.155093, + 0.0, 0.447059, 0.14902, + 0.0, 0.45098, 0.142809, + 0.0, 0.454902, 0.136477, + 0.0, 0.458824, 0.130007, + 0.0, 0.462745, 0.1234, + 0.0, 0.466667, 0.11667, + 0.0, 0.470588, 0.109804, + 0.0, 0.47451, 0.102815, + 0.0, 0.478431, 0.0956893, + 0.0, 0.482353, 0.088426, + 0.0, 0.486275, 0.0810407, + 0.0, 0.490196, 0.0735332, + 0.0, 0.494118, 0.0658885, + 0.0, 0.498039, 0.0581064, + 0.0, 0.501961, 0.0502022, + 0.0, 0.505882, 0.0421607, + 0.0, 0.509804, 0.0339818, + 0.0, 0.513725, 0.0256809, + 0.0, 0.517647, 0.017258, + 0.0, 0.521569, 0.00869764, + 0.0, 0.52549, 0.0, + 0.00881971, 0.529412, 0.0, + 0.0177768, 0.533333, 0.0, + 0.0268559, 0.537255, 0.0, + 0.0360723, 0.541176, 0.0, + 0.0454261, 0.545098, 0.0, + 0.054902, 0.54902, 0.0, + 0.0645151, 0.552941, 0.0, + 0.0742504, 0.556863, 0.0, + 0.084123, 0.560784, 0.0, + 0.0941176, 0.564706, 0.0, + 0.10425, 0.568627, 0.0, + 0.114504, 0.572549, 0.0, + 0.124895, 0.576471, 0.0, + 0.135424, 0.580392, 0.0, + 0.146075, 0.584314, 0.0, + 0.156863, 0.588235, 0.0, + 0.167773, 0.592157, 0.0, + 0.17882, 0.596078, 0.0, + 0.190005, 0.6, 0.0, + 0.201312, 0.603922, 0.0, + 0.212741, 0.607843, 0.0, + 0.224308, 0.611765, 0.0, + 0.236011, 0.615686, 0.0, + 0.247837, 0.619608, 0.0, + 0.2598, 0.623529, 0.0, + 0.271901, 0.627451, 0.0, + 0.284123, 0.631373, 0.0, + 0.296468, 0.635294, 0.0, + 0.308949, 0.639216, 0.0, + 0.321569, 0.643137, 0.0, + 0.33431, 0.647059, 0.0, + 0.347189, 0.65098, 0.0, + 0.360189, 0.654902, 0.0, + 0.373327, 0.658824, 0.0, + 0.386603, 0.662745, 0.0, + 0.4, 0.666667, 0.0, + 0.413535, 0.670588, 0.0, + 0.427192, 0.67451, 0.0, + 0.440986, 0.678431, 0.0, + 0.454902, 0.682353, 0.0, + 0.468956, 0.686275, 0.0, + 0.483131, 0.690196, 0.0, + 0.497444, 0.694118, 0.0, + 0.511894, 0.698039, 0.0, + 0.526467, 0.701961, 0.0, + 0.541176, 0.705882, 0.0, + 0.556008, 0.709804, 0.0, + 0.570977, 0.713725, 0.0, + 0.586084, 0.717647, 0.0, + 0.601312, 0.721569, 0.0, + 0.616663, 0.72549, 0.0, + 0.632151, 0.729412, 0.0, + 0.647776, 0.733333, 0.0, + 0.663523, 0.737255, 0.0, + 0.679408, 0.741176, 0.0, + 0.69543, 0.745098, 0.0, + 0.711574, 0.74902, 0.0, + 0.72784, 0.752941, 0.0, + 0.744244, 0.756863, 0.0, + 0.760784, 0.760784, 0.0, + 0.764706, 0.751965, 0.0, + 0.768627, 0.743008, 0.0, + 0.772549, 0.733928, 0.0, + 0.776471, 0.724712, 0.0, + 0.780392, 0.715358, 0.0, + 0.784314, 0.705882, 0.0, + 0.788235, 0.696269, 0.0, + 0.792157, 0.686534, 0.0, + 0.796078, 0.676661, 0.0, + 0.8, 0.666667, 0.0, + 0.803922, 0.656535, 0.0, + 0.807843, 0.646281, 0.0, + 0.811765, 0.635889, 0.0, + 0.815686, 0.62536, 0.0, + 0.819608, 0.61471, 0.0, + 0.823529, 0.603922, 0.0, + 0.827451, 0.593011, 0.0, + 0.831373, 0.581964, 0.0, + 0.835294, 0.570779, 0.0, + 0.839216, 0.559472, 0.0, + 0.843137, 0.548043, 0.0, + 0.847059, 0.536477, 0.0, + 0.85098, 0.524773, 0.0, + 0.854902, 0.512947, 0.0, + 0.858824, 0.500984, 0.0, + 0.862745, 0.488884, 0.0, + 0.866667, 0.476661, 0.0, + 0.870588, 0.464317, 0.0, + 0.87451, 0.451835, 0.0, + 0.878431, 0.439216, 0.0, + 0.882353, 0.426474, 0.0, + 0.886275, 0.413596, 0.0, + 0.890196, 0.400595, 0.0, + 0.894118, 0.387457, 0.0, + 0.898039, 0.374182, 0.0, + 0.901961, 0.360784, 0.0, + 0.905882, 0.34725, 0.0, + 0.909804, 0.333593, 0.0, + 0.913725, 0.319799, 0.0, + 0.917647, 0.305882, 0.0, + 0.921569, 0.291829, 0.0, + 0.92549, 0.277653, 0.0, + 0.929412, 0.26334, 0.0, + 0.933333, 0.24889, 0.0, + 0.937255, 0.234318, 0.0, + 0.941176, 0.219608, 0.0, + 0.945098, 0.204776, 0.0, + 0.94902, 0.189807, 0.0, + 0.952941, 0.174701, 0.0, + 0.956863, 0.159472, 0.0, + 0.960784, 0.144121, 0.0, + 0.964706, 0.128634, 0.0, + 0.968627, 0.113008, 0.0, + 0.972549, 0.097261, 0.0, + 0.976471, 0.0813764, 0.0, + 0.980392, 0.0653544, 0.0, + 0.984314, 0.0492103, 0.0, + 0.988235, 0.0329442, 0.0, + 0.992157, 0.0165408, 0.0, + 0.996078, 0.0, 0.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, + 1.0, 1.0, 1.0, +}; + +const float ColorMap::m_jet[m_size] = +{ + 0.0, 0.0, 0.5156, + 0.0, 0.0, 0.5312, + 0.0, 0.0, 0.5469, + 0.0, 0.0, 0.5625, + 0.0, 0.0, 0.5781, + 0.0, 0.0, 0.5938, + 0.0, 0.0, 0.6094, + 0.0, 0.0, 0.6250, + 0.0, 0.0, 0.6406, + 0.0, 0.0, 0.6562, + 0.0, 0.0, 0.6719, + 0.0, 0.0, 0.6875, + 0.0, 0.0, 0.7031, + 0.0, 0.0, 0.7188, + 0.0, 0.0, 0.7344, + 0.0, 0.0, 0.7500, + 0.0, 0.0, 0.7656, + 0.0, 0.0, 0.7812, + 0.0, 0.0, 0.7969, + 0.0, 0.0, 0.8125, + 0.0, 0.0, 0.8281, + 0.0, 0.0, 0.8438, + 0.0, 0.0, 0.8594, + 0.0, 0.0, 0.8750, + 0.0, 0.0, 0.8906, + 0.0, 0.0, 0.9062, + 0.0, 0.0, 0.9219, + 0.0, 0.0, 0.9375, + 0.0, 0.0, 0.9531, + 0.0, 0.0, 0.9688, + 0.0, 0.0, 0.9844, + 0.0, 0.0, 1.0000, + 0.0, 0.0156, 1.0000, + 0.0, 0.0312, 1.0000, + 0.0, 0.0469, 1.0000, + 0.0, 0.0625, 1.0000, + 0.0, 0.0781, 1.0000, + 0.0, 0.0938, 1.0000, + 0.0, 0.1094, 1.0000, + 0.0, 0.1250, 1.0000, + 0.0, 0.1406, 1.0000, + 0.0, 0.1562, 1.0000, + 0.0, 0.1719, 1.0000, + 0.0, 0.1875, 1.0000, + 0.0, 0.2031, 1.0000, + 0.0, 0.2188, 1.0000, + 0.0, 0.2344, 1.0000, + 0.0, 0.2500, 1.0000, + 0.0, 0.2656, 1.0000, + 0.0, 0.2812, 1.0000, + 0.0, 0.2969, 1.0000, + 0.0, 0.3125, 1.0000, + 0.0, 0.3281, 1.0000, + 0.0, 0.3438, 1.0000, + 0.0, 0.3594, 1.0000, + 0.0, 0.3750, 1.0000, + 0.0, 0.3906, 1.0000, + 0.0, 0.4062, 1.0000, + 0.0, 0.4219, 1.0000, + 0.0, 0.4375, 1.0000, + 0.0, 0.4531, 1.0000, + 0.0, 0.4688, 1.0000, + 0.0, 0.4844, 1.0000, + 0.0, 0.5000, 1.0000, + 0.0, 0.5156, 1.0000, + 0.0, 0.5312, 1.0000, + 0.0, 0.5469, 1.0000, + 0.0, 0.5625, 1.0000, + 0.0, 0.5781, 1.0000, + 0.0, 0.5938, 1.0000, + 0.0, 0.6094, 1.0000, + 0.0, 0.6250, 1.0000, + 0.0, 0.6406, 1.0000, + 0.0, 0.6562, 1.0000, + 0.0, 0.6719, 1.0000, + 0.0, 0.6875, 1.0000, + 0.0, 0.7031, 1.0000, + 0.0, 0.7188, 1.0000, + 0.0, 0.7344, 1.0000, + 0.0, 0.7500, 1.0000, + 0.0, 0.7656, 1.0000, + 0.0, 0.7812, 1.0000, + 0.0, 0.7969, 1.0000, + 0.0, 0.8125, 1.0000, + 0.0, 0.8281, 1.0000, + 0.0, 0.8438, 1.0000, + 0.0, 0.8594, 1.0000, + 0.0, 0.8750, 1.0000, + 0.0, 0.8906, 1.0000, + 0.0, 0.9062, 1.0000, + 0.0, 0.9219, 1.0000, + 0.0, 0.9375, 1.0000, + 0.0, 0.9531, 1.0000, + 0.0, 0.9688, 1.0000, + 0.0, 0.9844, 1.0000, + 0.0, 1.0000, 1.0000, + 0.0156, 1.0000, 0.9844, + 0.0312, 1.0000, 0.9688, + 0.0469, 1.0000, 0.9531, + 0.0625, 1.0000, 0.9375, + 0.0781, 1.0000, 0.9219, + 0.0938, 1.0000, 0.9062, + 0.1094, 1.0000, 0.8906, + 0.1250, 1.0000, 0.8750, + 0.1406, 1.0000, 0.8594, + 0.1562, 1.0000, 0.8438, + 0.1719, 1.0000, 0.8281, + 0.1875, 1.0000, 0.8125, + 0.2031, 1.0000, 0.7969, + 0.2188, 1.0000, 0.7812, + 0.2344, 1.0000, 0.7656, + 0.2500, 1.0000, 0.7500, + 0.2656, 1.0000, 0.7344, + 0.2812, 1.0000, 0.7188, + 0.2969, 1.0000, 0.7031, + 0.3125, 1.0000, 0.6875, + 0.3281, 1.0000, 0.6719, + 0.3438, 1.0000, 0.6562, + 0.3594, 1.0000, 0.6406, + 0.3750, 1.0000, 0.6250, + 0.3906, 1.0000, 0.6094, + 0.4062, 1.0000, 0.5938, + 0.4219, 1.0000, 0.5781, + 0.4375, 1.0000, 0.5625, + 0.4531, 1.0000, 0.5469, + 0.4688, 1.0000, 0.5312, + 0.4844, 1.0000, 0.5156, + 0.5000, 1.0000, 0.5000, + 0.5156, 1.0000, 0.4844, + 0.5312, 1.0000, 0.4688, + 0.5469, 1.0000, 0.4531, + 0.5625, 1.0000, 0.4375, + 0.5781, 1.0000, 0.4219, + 0.5938, 1.0000, 0.4062, + 0.6094, 1.0000, 0.3906, + 0.6250, 1.0000, 0.3750, + 0.6406, 1.0000, 0.3594, + 0.6562, 1.0000, 0.3438, + 0.6719, 1.0000, 0.3281, + 0.6875, 1.0000, 0.3125, + 0.7031, 1.0000, 0.2969, + 0.7188, 1.0000, 0.2812, + 0.7344, 1.0000, 0.2656, + 0.7500, 1.0000, 0.2500, + 0.7656, 1.0000, 0.2344, + 0.7812, 1.0000, 0.2188, + 0.7969, 1.0000, 0.2031, + 0.8125, 1.0000, 0.1875, + 0.8281, 1.0000, 0.1719, + 0.8438, 1.0000, 0.1562, + 0.8594, 1.0000, 0.1406, + 0.8750, 1.0000, 0.1250, + 0.8906, 1.0000, 0.1094, + 0.9062, 1.0000, 0.0938, + 0.9219, 1.0000, 0.0781, + 0.9375, 1.0000, 0.0625, + 0.9531, 1.0000, 0.0469, + 0.9688, 1.0000, 0.0312, + 0.9844, 1.0000, 0.0156, + 1.0000, 1.0000, 0.0, + 1.0000, 0.9844, 0.0, + 1.0000, 0.9688, 0.0, + 1.0000, 0.9531, 0.0, + 1.0000, 0.9375, 0.0, + 1.0000, 0.9219, 0.0, + 1.0000, 0.9062, 0.0, + 1.0000, 0.8906, 0.0, + 1.0000, 0.8750, 0.0, + 1.0000, 0.8594, 0.0, + 1.0000, 0.8438, 0.0, + 1.0000, 0.8281, 0.0, + 1.0000, 0.8125, 0.0, + 1.0000, 0.7969, 0.0, + 1.0000, 0.7812, 0.0, + 1.0000, 0.7656, 0.0, + 1.0000, 0.7500, 0.0, + 1.0000, 0.7344, 0.0, + 1.0000, 0.7188, 0.0, + 1.0000, 0.7031, 0.0, + 1.0000, 0.6875, 0.0, + 1.0000, 0.6719, 0.0, + 1.0000, 0.6562, 0.0, + 1.0000, 0.6406, 0.0, + 1.0000, 0.6250, 0.0, + 1.0000, 0.6094, 0.0, + 1.0000, 0.5938, 0.0, + 1.0000, 0.5781, 0.0, + 1.0000, 0.5625, 0.0, + 1.0000, 0.5469, 0.0, + 1.0000, 0.5312, 0.0, + 1.0000, 0.5156, 0.0, + 1.0000, 0.5000, 0.0, + 1.0000, 0.4844, 0.0, + 1.0000, 0.4688, 0.0, + 1.0000, 0.4531, 0.0, + 1.0000, 0.4375, 0.0, + 1.0000, 0.4219, 0.0, + 1.0000, 0.4062, 0.0, + 1.0000, 0.3906, 0.0, + 1.0000, 0.3750, 0.0, + 1.0000, 0.3594, 0.0, + 1.0000, 0.3438, 0.0, + 1.0000, 0.3281, 0.0, + 1.0000, 0.3125, 0.0, + 1.0000, 0.2969, 0.0, + 1.0000, 0.2812, 0.0, + 1.0000, 0.2656, 0.0, + 1.0000, 0.2500, 0.0, + 1.0000, 0.2344, 0.0, + 1.0000, 0.2188, 0.0, + 1.0000, 0.2031, 0.0, + 1.0000, 0.1875, 0.0, + 1.0000, 0.1719, 0.0, + 1.0000, 0.1562, 0.0, + 1.0000, 0.1406, 0.0, + 1.0000, 0.1250, 0.0, + 1.0000, 0.1094, 0.0, + 1.0000, 0.0938, 0.0, + 1.0000, 0.0781, 0.0, + 1.0000, 0.0625, 0.0, + 1.0000, 0.0469, 0.0, + 1.0000, 0.0312, 0.0, + 1.0000, 0.0156, 0.0, + 1.0000, 0.0, 0.0, + 0.9844, 0.0, 0.0, + 0.9688, 0.0, 0.0, + 0.9531, 0.0, 0.0, + 0.9375, 0.0, 0.0, + 0.9219, 0.0, 0.0, + 0.9062, 0.0, 0.0, + 0.8906, 0.0, 0.0, + 0.8750, 0.0, 0.0, + 0.8594, 0.0, 0.0, + 0.8438, 0.0, 0.0, + 0.8281, 0.0, 0.0, + 0.8125, 0.0, 0.0, + 0.7969, 0.0, 0.0, + 0.7812, 0.0, 0.0, + 0.7656, 0.0, 0.0, + 0.7500, 0.0, 0.0, + 0.7344, 0.0, 0.0, + 0.7188, 0.0, 0.0, + 0.7031, 0.0, 0.0, + 0.6875, 0.0, 0.0, + 0.6719, 0.0, 0.0, + 0.6562, 0.0, 0.0, + 0.6406, 0.0, 0.0, + 0.6250, 0.0, 0.0, + 0.6094, 0.0, 0.0, + 0.5938, 0.0, 0.0, + 0.5781, 0.0, 0.0, + 0.5625, 0.0, 0.0, + 0.5469, 0.0, 0.0, + 0.5312, 0.0, 0.0, + 0.5156, 0.0, 0.0, + 0.5000, 0.0, 0.0, +}; + +const float ColorMap::m_turbo[m_size] = +{ + 0.1900, 0.0718, 0.2322, + 0.1948, 0.0834, 0.2615, + 0.1996, 0.0950, 0.2902, + 0.2041, 0.1065, 0.3184, + 0.2086, 0.1180, 0.3461, + 0.2129, 0.1295, 0.3731, + 0.2171, 0.1409, 0.3996, + 0.2211, 0.1522, 0.4256, + 0.2250, 0.1635, 0.4510, + 0.2288, 0.1748, 0.4758, + 0.2324, 0.1860, 0.5000, + 0.2358, 0.1972, 0.5237, + 0.2392, 0.2083, 0.5469, + 0.2423, 0.2194, 0.5694, + 0.2454, 0.2304, 0.5914, + 0.2483, 0.2414, 0.6129, + 0.2511, 0.2524, 0.6337, + 0.2537, 0.2633, 0.6541, + 0.2562, 0.2741, 0.6738, + 0.2585, 0.2849, 0.6930, + 0.2607, 0.2957, 0.7116, + 0.2628, 0.3064, 0.7297, + 0.2647, 0.3171, 0.7472, + 0.2665, 0.3277, 0.7641, + 0.2682, 0.3382, 0.7805, + 0.2697, 0.3488, 0.7963, + 0.2710, 0.3593, 0.8116, + 0.2723, 0.3697, 0.8262, + 0.2733, 0.3801, 0.8404, + 0.2743, 0.3904, 0.8539, + 0.2751, 0.4007, 0.8669, + 0.2758, 0.4110, 0.8794, + 0.2763, 0.4212, 0.8912, + 0.2767, 0.4313, 0.9025, + 0.2769, 0.4415, 0.9133, + 0.2770, 0.4515, 0.9235, + 0.2770, 0.4615, 0.9331, + 0.2768, 0.4715, 0.9421, + 0.2765, 0.4814, 0.9506, + 0.2760, 0.4913, 0.9586, + 0.2754, 0.5011, 0.9659, + 0.2747, 0.5109, 0.9728, + 0.2738, 0.5207, 0.9790, + 0.2727, 0.5304, 0.9846, + 0.2711, 0.5402, 0.9893, + 0.2688, 0.5500, 0.9930, + 0.2659, 0.5598, 0.9958, + 0.2625, 0.5697, 0.9977, + 0.2586, 0.5796, 0.9988, + 0.2542, 0.5895, 0.9990, + 0.2495, 0.5994, 0.9983, + 0.2443, 0.6094, 0.9970, + 0.2387, 0.6193, 0.9949, + 0.2329, 0.6292, 0.9920, + 0.2268, 0.6391, 0.9885, + 0.2204, 0.6490, 0.9844, + 0.2138, 0.6589, 0.9796, + 0.2071, 0.6687, 0.9742, + 0.2002, 0.6784, 0.9683, + 0.1933, 0.6881, 0.9619, + 0.1862, 0.6977, 0.9550, + 0.1792, 0.7073, 0.9476, + 0.1722, 0.7168, 0.9398, + 0.1653, 0.7262, 0.9316, + 0.1584, 0.7355, 0.9231, + 0.1517, 0.7447, 0.9142, + 0.1452, 0.7538, 0.9050, + 0.1389, 0.7628, 0.8955, + 0.1328, 0.7716, 0.8858, + 0.1270, 0.7804, 0.8759, + 0.1215, 0.7890, 0.8658, + 0.1164, 0.7974, 0.8556, + 0.1117, 0.8057, 0.8452, + 0.1074, 0.8138, 0.8348, + 0.1036, 0.8218, 0.8244, + 0.1003, 0.8296, 0.8139, + 0.0975, 0.8371, 0.8034, + 0.0953, 0.8446, 0.7930, + 0.0938, 0.8518, 0.7826, + 0.0929, 0.8588, 0.7724, + 0.0927, 0.8655, 0.7623, + 0.0932, 0.8721, 0.7524, + 0.0945, 0.8784, 0.7427, + 0.0966, 0.8845, 0.7332, + 0.0996, 0.8904, 0.7239, + 0.1034, 0.8960, 0.7150, + 0.1081, 0.9014, 0.7060, + 0.1137, 0.9067, 0.6965, + 0.1201, 0.9119, 0.6866, + 0.1273, 0.9170, 0.6763, + 0.1353, 0.9220, 0.6656, + 0.1439, 0.9268, 0.6545, + 0.1532, 0.9315, 0.6431, + 0.1632, 0.9361, 0.6314, + 0.1738, 0.9405, 0.6194, + 0.1849, 0.9448, 0.6071, + 0.1966, 0.9490, 0.5947, + 0.2088, 0.9530, 0.5820, + 0.2214, 0.9569, 0.5691, + 0.2345, 0.9607, 0.5561, + 0.2480, 0.9642, 0.5430, + 0.2618, 0.9677, 0.5298, + 0.2760, 0.9709, 0.5165, + 0.2904, 0.9740, 0.5032, + 0.3051, 0.9770, 0.4899, + 0.3201, 0.9797, 0.4765, + 0.3352, 0.9823, 0.4632, + 0.3504, 0.9848, 0.4500, + 0.3658, 0.9870, 0.4369, + 0.3813, 0.9891, 0.4239, + 0.3968, 0.9910, 0.4110, + 0.4123, 0.9927, 0.3983, + 0.4278, 0.9942, 0.3857, + 0.4432, 0.9955, 0.3735, + 0.4585, 0.9966, 0.3614, + 0.4738, 0.9976, 0.3496, + 0.4888, 0.9983, 0.3382, + 0.5036, 0.9988, 0.3270, + 0.5182, 0.9991, 0.3162, + 0.5325, 0.9992, 0.3058, + 0.5466, 0.9991, 0.2958, + 0.5603, 0.9987, 0.2862, + 0.5736, 0.9982, 0.2771, + 0.5865, 0.9974, 0.2685, + 0.5989, 0.9964, 0.2604, + 0.6109, 0.9951, 0.2528, + 0.6223, 0.9937, 0.2458, + 0.6332, 0.9919, 0.2394, + 0.6436, 0.9900, 0.2336, + 0.6539, 0.9878, 0.2283, + 0.6643, 0.9852, 0.2237, + 0.6746, 0.9825, 0.2196, + 0.6849, 0.9794, 0.2160, + 0.6953, 0.9761, 0.2129, + 0.7055, 0.9726, 0.2103, + 0.7158, 0.9688, 0.2082, + 0.7260, 0.9647, 0.2064, + 0.7361, 0.9604, 0.2050, + 0.7462, 0.9559, 0.2041, + 0.7562, 0.9512, 0.2034, + 0.7661, 0.9463, 0.2031, + 0.7759, 0.9411, 0.2031, + 0.7856, 0.9358, 0.2034, + 0.7952, 0.9303, 0.2039, + 0.8047, 0.9245, 0.2046, + 0.8141, 0.9186, 0.2055, + 0.8233, 0.9125, 0.2066, + 0.8324, 0.9063, 0.2079, + 0.8413, 0.8999, 0.2093, + 0.8501, 0.8933, 0.2107, + 0.8587, 0.8865, 0.2123, + 0.8671, 0.8797, 0.2139, + 0.8753, 0.8727, 0.2155, + 0.8833, 0.8655, 0.2172, + 0.8911, 0.8583, 0.2188, + 0.8987, 0.8509, 0.2204, + 0.9061, 0.8434, 0.2219, + 0.9132, 0.8358, 0.2233, + 0.9200, 0.8281, 0.2246, + 0.9267, 0.8203, 0.2257, + 0.9330, 0.8124, 0.2267, + 0.9391, 0.8044, 0.2274, + 0.9449, 0.7963, 0.2280, + 0.9504, 0.7882, 0.2283, + 0.9556, 0.7801, 0.2284, + 0.9605, 0.7718, 0.2281, + 0.9651, 0.7635, 0.2275, + 0.9693, 0.7552, 0.2266, + 0.9732, 0.7468, 0.2254, + 0.9768, 0.7384, 0.2237, + 0.9800, 0.7300, 0.2216, + 0.9829, 0.7214, 0.2192, + 0.9855, 0.7125, 0.2165, + 0.9878, 0.7033, 0.2136, + 0.9899, 0.6938, 0.2104, + 0.9916, 0.6841, 0.2071, + 0.9931, 0.6741, 0.2035, + 0.9944, 0.6639, 0.1997, + 0.9953, 0.6534, 0.1958, + 0.9961, 0.6428, 0.1916, + 0.9965, 0.6319, 0.1874, + 0.9968, 0.6209, 0.1830, + 0.9967, 0.6098, 0.1784, + 0.9964, 0.5985, 0.1738, + 0.9959, 0.5870, 0.1690, + 0.9952, 0.5755, 0.1641, + 0.9942, 0.5639, 0.1592, + 0.9930, 0.5521, 0.1542, + 0.9915, 0.5404, 0.1491, + 0.9899, 0.5285, 0.1440, + 0.9880, 0.5167, 0.1388, + 0.9859, 0.5048, 0.1337, + 0.9836, 0.4929, 0.1285, + 0.9811, 0.4810, 0.1233, + 0.9784, 0.4692, 0.1182, + 0.9755, 0.4574, 0.1130, + 0.9723, 0.4456, 0.1080, + 0.9690, 0.4340, 0.1029, + 0.9656, 0.4224, 0.0980, + 0.9619, 0.4109, 0.0931, + 0.9580, 0.3996, 0.0883, + 0.9540, 0.3884, 0.0836, + 0.9498, 0.3773, 0.0790, + 0.9454, 0.3664, 0.0746, + 0.9408, 0.3557, 0.0703, + 0.9361, 0.3451, 0.0662, + 0.9313, 0.3348, 0.0622, + 0.9262, 0.3247, 0.0584, + 0.9211, 0.3149, 0.0548, + 0.9157, 0.3053, 0.0513, + 0.9102, 0.2960, 0.0481, + 0.9046, 0.2870, 0.0452, + 0.8989, 0.2782, 0.0424, + 0.8930, 0.2698, 0.0399, + 0.8869, 0.2615, 0.0375, + 0.8807, 0.2533, 0.0352, + 0.8742, 0.2453, 0.0330, + 0.8676, 0.2373, 0.0308, + 0.8608, 0.2294, 0.0288, + 0.8538, 0.2217, 0.0268, + 0.8466, 0.2141, 0.0249, + 0.8393, 0.2065, 0.0231, + 0.8317, 0.1991, 0.0213, + 0.8240, 0.1918, 0.0197, + 0.8161, 0.1846, 0.0181, + 0.8080, 0.1775, 0.0166, + 0.7997, 0.1706, 0.0152, + 0.7913, 0.1637, 0.0139, + 0.7826, 0.1569, 0.0126, + 0.7738, 0.1503, 0.0115, + 0.7648, 0.1437, 0.0104, + 0.7556, 0.1373, 0.0094, + 0.7462, 0.1310, 0.0085, + 0.7366, 0.1248, 0.0077, + 0.7269, 0.1187, 0.0069, + 0.7169, 0.1127, 0.0063, + 0.7068, 0.1068, 0.0057, + 0.6965, 0.1010, 0.0052, + 0.6860, 0.0954, 0.0048, + 0.6754, 0.0898, 0.0045, + 0.6645, 0.0844, 0.0042, + 0.6534, 0.0790, 0.0041, + 0.6422, 0.0738, 0.0040, + 0.6308, 0.0687, 0.0040, + 0.6192, 0.0637, 0.0041, + 0.6075, 0.0588, 0.0043, + 0.5955, 0.0540, 0.0045, + 0.5834, 0.0493, 0.0049, + 0.5710, 0.0447, 0.0053, + 0.5585, 0.0403, 0.0058, + 0.5458, 0.0359, 0.0064, + 0.5330, 0.0317, 0.0070, + 0.5199, 0.0276, 0.0078, + 0.5066, 0.0235, 0.0086, + 0.4932, 0.0196, 0.0095, + 0.4796, 0.0158, 0.0106, +}; + +const float ColorMap::m_parula[m_size] = +{ + 0.2422, 0.1504, 0.6603, + 0.2444, 0.1534, 0.6728, + 0.2464, 0.1569, 0.6847, + 0.2484, 0.1607, 0.6961, + 0.2503, 0.1648, 0.7071, + 0.2522, 0.1689, 0.7179, + 0.2540, 0.1732, 0.7286, + 0.2558, 0.1773, 0.7393, + 0.2576, 0.1814, 0.7501, + 0.2594, 0.1854, 0.7610, + 0.2611, 0.1893, 0.7719, + 0.2628, 0.1932, 0.7828, + 0.2645, 0.1972, 0.7937, + 0.2661, 0.2011, 0.8043, + 0.2676, 0.2052, 0.8148, + 0.2691, 0.2094, 0.8249, + 0.2704, 0.2138, 0.8346, + 0.2717, 0.2184, 0.8439, + 0.2729, 0.2231, 0.8528, + 0.2740, 0.2280, 0.8612, + 0.2749, 0.2330, 0.8692, + 0.2758, 0.2382, 0.8767, + 0.2766, 0.2435, 0.8840, + 0.2774, 0.2489, 0.8908, + 0.2781, 0.2543, 0.8973, + 0.2788, 0.2598, 0.9035, + 0.2794, 0.2653, 0.9094, + 0.2798, 0.2708, 0.9150, + 0.2802, 0.2764, 0.9204, + 0.2806, 0.2819, 0.9255, + 0.2809, 0.2875, 0.9305, + 0.2811, 0.2930, 0.9352, + 0.2813, 0.2985, 0.9397, + 0.2814, 0.3040, 0.9441, + 0.2814, 0.3095, 0.9483, + 0.2813, 0.3150, 0.9524, + 0.2811, 0.3204, 0.9563, + 0.2809, 0.3259, 0.9600, + 0.2807, 0.3313, 0.9636, + 0.2803, 0.3367, 0.9670, + 0.2798, 0.3421, 0.9702, + 0.2791, 0.3475, 0.9733, + 0.2784, 0.3529, 0.9763, + 0.2776, 0.3583, 0.9791, + 0.2766, 0.3638, 0.9817, + 0.2754, 0.3693, 0.9840, + 0.2741, 0.3748, 0.9862, + 0.2726, 0.3804, 0.9881, + 0.2710, 0.3860, 0.9898, + 0.2691, 0.3916, 0.9912, + 0.2670, 0.3973, 0.9924, + 0.2647, 0.4030, 0.9935, + 0.2621, 0.4088, 0.9946, + 0.2591, 0.4145, 0.9955, + 0.2556, 0.4203, 0.9965, + 0.2517, 0.4261, 0.9974, + 0.2473, 0.4319, 0.9983, + 0.2424, 0.4378, 0.9991, + 0.2369, 0.4437, 0.9996, + 0.2311, 0.4497, 0.9995, + 0.2250, 0.4559, 0.9985, + 0.2189, 0.4620, 0.9968, + 0.2128, 0.4682, 0.9948, + 0.2066, 0.4743, 0.9926, + 0.2006, 0.4803, 0.9906, + 0.1950, 0.4861, 0.9887, + 0.1903, 0.4919, 0.9867, + 0.1869, 0.4975, 0.9844, + 0.1847, 0.5030, 0.9819, + 0.1831, 0.5084, 0.9793, + 0.1818, 0.5138, 0.9766, + 0.1806, 0.5191, 0.9738, + 0.1795, 0.5244, 0.9709, + 0.1785, 0.5296, 0.9677, + 0.1778, 0.5349, 0.9641, + 0.1773, 0.5401, 0.9602, + 0.1768, 0.5452, 0.9560, + 0.1764, 0.5504, 0.9516, + 0.1755, 0.5554, 0.9473, + 0.1740, 0.5605, 0.9432, + 0.1716, 0.5655, 0.9393, + 0.1686, 0.5705, 0.9357, + 0.1649, 0.5755, 0.9323, + 0.1610, 0.5805, 0.9289, + 0.1573, 0.5854, 0.9254, + 0.1540, 0.5902, 0.9218, + 0.1513, 0.5950, 0.9182, + 0.1492, 0.5997, 0.9147, + 0.1475, 0.6043, 0.9113, + 0.1461, 0.6089, 0.9080, + 0.1446, 0.6135, 0.9050, + 0.1429, 0.6180, 0.9022, + 0.1408, 0.6226, 0.8998, + 0.1383, 0.6272, 0.8975, + 0.1354, 0.6317, 0.8953, + 0.1321, 0.6363, 0.8932, + 0.1288, 0.6408, 0.8910, + 0.1253, 0.6453, 0.8887, + 0.1219, 0.6497, 0.8862, + 0.1185, 0.6541, 0.8834, + 0.1152, 0.6584, 0.8804, + 0.1119, 0.6627, 0.8770, + 0.1085, 0.6669, 0.8734, + 0.1048, 0.6710, 0.8695, + 0.1009, 0.6750, 0.8653, + 0.0964, 0.6789, 0.8609, + 0.0914, 0.6828, 0.8562, + 0.0855, 0.6865, 0.8513, + 0.0789, 0.6902, 0.8462, + 0.0713, 0.6938, 0.8409, + 0.0628, 0.6972, 0.8355, + 0.0535, 0.7006, 0.8299, + 0.0433, 0.7039, 0.8242, + 0.0328, 0.7071, 0.8183, + 0.0234, 0.7103, 0.8124, + 0.0155, 0.7133, 0.8064, + 0.0091, 0.7163, 0.8003, + 0.0046, 0.7192, 0.7941, + 0.0019, 0.7220, 0.7878, + 0.0009, 0.7248, 0.7815, + 0.0018, 0.7275, 0.7752, + 0.0046, 0.7301, 0.7688, + 0.0094, 0.7327, 0.7623, + 0.0162, 0.7352, 0.7558, + 0.0253, 0.7376, 0.7492, + 0.0369, 0.7400, 0.7426, + 0.0504, 0.7423, 0.7359, + 0.0638, 0.7446, 0.7292, + 0.0770, 0.7468, 0.7224, + 0.0899, 0.7489, 0.7156, + 0.1023, 0.7510, 0.7088, + 0.1141, 0.7531, 0.7019, + 0.1252, 0.7552, 0.6950, + 0.1354, 0.7572, 0.6881, + 0.1448, 0.7593, 0.6812, + 0.1532, 0.7614, 0.6741, + 0.1609, 0.7635, 0.6671, + 0.1678, 0.7656, 0.6599, + 0.1741, 0.7678, 0.6527, + 0.1799, 0.7699, 0.6454, + 0.1853, 0.7721, 0.6379, + 0.1905, 0.7743, 0.6303, + 0.1954, 0.7765, 0.6225, + 0.2003, 0.7787, 0.6146, + 0.2061, 0.7808, 0.6065, + 0.2118, 0.7828, 0.5983, + 0.2178, 0.7849, 0.5899, + 0.2244, 0.7869, 0.5813, + 0.2318, 0.7887, 0.5725, + 0.2401, 0.7905, 0.5636, + 0.2491, 0.7922, 0.5546, + 0.2589, 0.7937, 0.5454, + 0.2695, 0.7951, 0.5360, + 0.2809, 0.7964, 0.5266, + 0.2929, 0.7975, 0.5170, + 0.3052, 0.7985, 0.5074, + 0.3176, 0.7994, 0.4975, + 0.3301, 0.8002, 0.4876, + 0.3424, 0.8009, 0.4774, + 0.3548, 0.8016, 0.4669, + 0.3671, 0.8021, 0.4563, + 0.3795, 0.8026, 0.4454, + 0.3921, 0.8029, 0.4344, + 0.4050, 0.8031, 0.4233, + 0.4184, 0.8030, 0.4122, + 0.4322, 0.8028, 0.4013, + 0.4463, 0.8024, 0.3904, + 0.4608, 0.8018, 0.3797, + 0.4753, 0.8011, 0.3691, + 0.4899, 0.8002, 0.3586, + 0.5044, 0.7993, 0.3480, + 0.5187, 0.7982, 0.3374, + 0.5329, 0.7970, 0.3267, + 0.5470, 0.7957, 0.3159, + 0.5609, 0.7943, 0.3050, + 0.5748, 0.7929, 0.2941, + 0.5886, 0.7913, 0.2833, + 0.6024, 0.7896, 0.2726, + 0.6161, 0.7878, 0.2622, + 0.6297, 0.7859, 0.2521, + 0.6433, 0.7839, 0.2423, + 0.6567, 0.7818, 0.2329, + 0.6701, 0.7796, 0.2239, + 0.6833, 0.7773, 0.2155, + 0.6963, 0.7750, 0.2075, + 0.7091, 0.7727, 0.1998, + 0.7218, 0.7703, 0.1924, + 0.7344, 0.7679, 0.1852, + 0.7468, 0.7654, 0.1782, + 0.7590, 0.7629, 0.1717, + 0.7710, 0.7604, 0.1658, + 0.7829, 0.7579, 0.1608, + 0.7945, 0.7554, 0.1570, + 0.8060, 0.7529, 0.1546, + 0.8172, 0.7505, 0.1535, + 0.8281, 0.7481, 0.1536, + 0.8389, 0.7457, 0.1546, + 0.8495, 0.7435, 0.1564, + 0.8600, 0.7413, 0.1587, + 0.8703, 0.7392, 0.1615, + 0.8804, 0.7372, 0.1650, + 0.8903, 0.7353, 0.1695, + 0.9000, 0.7336, 0.1749, + 0.9093, 0.7321, 0.1815, + 0.9184, 0.7308, 0.1890, + 0.9272, 0.7298, 0.1973, + 0.9357, 0.7290, 0.2061, + 0.9440, 0.7285, 0.2151, + 0.9523, 0.7284, 0.2237, + 0.9606, 0.7285, 0.2312, + 0.9689, 0.7292, 0.2373, + 0.9770, 0.7304, 0.2418, + 0.9842, 0.7330, 0.2446, + 0.9900, 0.7365, 0.2429, + 0.9946, 0.7407, 0.2394, + 0.9966, 0.7458, 0.2351, + 0.9971, 0.7513, 0.2309, + 0.9972, 0.7569, 0.2267, + 0.9971, 0.7626, 0.2224, + 0.9969, 0.7683, 0.2181, + 0.9966, 0.7740, 0.2138, + 0.9962, 0.7798, 0.2095, + 0.9957, 0.7856, 0.2053, + 0.9949, 0.7915, 0.2012, + 0.9938, 0.7974, 0.1974, + 0.9923, 0.8034, 0.1939, + 0.9906, 0.8095, 0.1906, + 0.9885, 0.8156, 0.1875, + 0.9861, 0.8218, 0.1846, + 0.9835, 0.8280, 0.1817, + 0.9807, 0.8342, 0.1787, + 0.9778, 0.8404, 0.1757, + 0.9748, 0.8467, 0.1726, + 0.9720, 0.8529, 0.1695, + 0.9694, 0.8591, 0.1665, + 0.9671, 0.8654, 0.1636, + 0.9651, 0.8716, 0.1608, + 0.9634, 0.8778, 0.1582, + 0.9619, 0.8840, 0.1557, + 0.9608, 0.8902, 0.1532, + 0.9601, 0.8963, 0.1507, + 0.9596, 0.9023, 0.1480, + 0.9595, 0.9084, 0.1450, + 0.9597, 0.9143, 0.1418, + 0.9601, 0.9203, 0.1382, + 0.9608, 0.9262, 0.1344, + 0.9618, 0.9320, 0.1304, + 0.9629, 0.9379, 0.1261, + 0.9642, 0.9437, 0.1216, + 0.9657, 0.9494, 0.1168, + 0.9674, 0.9552, 0.1116, + 0.9692, 0.9609, 0.1061, + 0.9711, 0.9667, 0.1001, + 0.9730, 0.9724, 0.0938, + 0.9749, 0.9782, 0.0872, + 0.9769, 0.9839, 0.0805, +}; + +const float ColorMap::m_hot[m_size] = +{ + 0.0104, 0.0, 0.0, + 0.0208, 0.0, 0.0, + 0.0312, 0.0, 0.0, + 0.0417, 0.0, 0.0, + 0.0521, 0.0, 0.0, + 0.0625, 0.0, 0.0, + 0.0729, 0.0, 0.0, + 0.0833, 0.0, 0.0, + 0.0938, 0.0, 0.0, + 0.1042, 0.0, 0.0, + 0.1146, 0.0, 0.0, + 0.1250, 0.0, 0.0, + 0.1354, 0.0, 0.0, + 0.1458, 0.0, 0.0, + 0.1562, 0.0, 0.0, + 0.1667, 0.0, 0.0, + 0.1771, 0.0, 0.0, + 0.1875, 0.0, 0.0, + 0.1979, 0.0, 0.0, + 0.2083, 0.0, 0.0, + 0.2188, 0.0, 0.0, + 0.2292, 0.0, 0.0, + 0.2396, 0.0, 0.0, + 0.2500, 0.0, 0.0, + 0.2604, 0.0, 0.0, + 0.2708, 0.0, 0.0, + 0.2812, 0.0, 0.0, + 0.2917, 0.0, 0.0, + 0.3021, 0.0, 0.0, + 0.3125, 0.0, 0.0, + 0.3229, 0.0, 0.0, + 0.3333, 0.0, 0.0, + 0.3438, 0.0, 0.0, + 0.3542, 0.0, 0.0, + 0.3646, 0.0, 0.0, + 0.3750, 0.0, 0.0, + 0.3854, 0.0, 0.0, + 0.3958, 0.0, 0.0, + 0.4062, 0.0, 0.0, + 0.4167, 0.0, 0.0, + 0.4271, 0.0, 0.0, + 0.4375, 0.0, 0.0, + 0.4479, 0.0, 0.0, + 0.4583, 0.0, 0.0, + 0.4688, 0.0, 0.0, + 0.4792, 0.0, 0.0, + 0.4896, 0.0, 0.0, + 0.5000, 0.0, 0.0, + 0.5104, 0.0, 0.0, + 0.5208, 0.0, 0.0, + 0.5312, 0.0, 0.0, + 0.5417, 0.0, 0.0, + 0.5521, 0.0, 0.0, + 0.5625, 0.0, 0.0, + 0.5729, 0.0, 0.0, + 0.5833, 0.0, 0.0, + 0.5938, 0.0, 0.0, + 0.6042, 0.0, 0.0, + 0.6146, 0.0, 0.0, + 0.6250, 0.0, 0.0, + 0.6354, 0.0, 0.0, + 0.6458, 0.0, 0.0, + 0.6562, 0.0, 0.0, + 0.6667, 0.0, 0.0, + 0.6771, 0.0, 0.0, + 0.6875, 0.0, 0.0, + 0.6979, 0.0, 0.0, + 0.7083, 0.0, 0.0, + 0.7188, 0.0, 0.0, + 0.7292, 0.0, 0.0, + 0.7396, 0.0, 0.0, + 0.7500, 0.0, 0.0, + 0.7604, 0.0, 0.0, + 0.7708, 0.0, 0.0, + 0.7812, 0.0, 0.0, + 0.7917, 0.0, 0.0, + 0.8021, 0.0, 0.0, + 0.8125, 0.0, 0.0, + 0.8229, 0.0, 0.0, + 0.8333, 0.0, 0.0, + 0.8438, 0.0, 0.0, + 0.8542, 0.0, 0.0, + 0.8646, 0.0, 0.0, + 0.8750, 0.0, 0.0, + 0.8854, 0.0, 0.0, + 0.8958, 0.0, 0.0, + 0.9062, 0.0, 0.0, + 0.9167, 0.0, 0.0, + 0.9271, 0.0, 0.0, + 0.9375, 0.0, 0.0, + 0.9479, 0.0, 0.0, + 0.9583, 0.0, 0.0, + 0.9688, 0.0, 0.0, + 0.9792, 0.0, 0.0, + 0.9896, 0.0, 0.0, + 1.0000, 0.0, 0.0, + 1.0000, 0.0104, 0.0, + 1.0000, 0.0208, 0.0, + 1.0000, 0.0312, 0.0, + 1.0000, 0.0417, 0.0, + 1.0000, 0.0521, 0.0, + 1.0000, 0.0625, 0.0, + 1.0000, 0.0729, 0.0, + 1.0000, 0.0833, 0.0, + 1.0000, 0.0938, 0.0, + 1.0000, 0.1042, 0.0, + 1.0000, 0.1146, 0.0, + 1.0000, 0.1250, 0.0, + 1.0000, 0.1354, 0.0, + 1.0000, 0.1458, 0.0, + 1.0000, 0.1562, 0.0, + 1.0000, 0.1667, 0.0, + 1.0000, 0.1771, 0.0, + 1.0000, 0.1875, 0.0, + 1.0000, 0.1979, 0.0, + 1.0000, 0.2083, 0.0, + 1.0000, 0.2188, 0.0, + 1.0000, 0.2292, 0.0, + 1.0000, 0.2396, 0.0, + 1.0000, 0.2500, 0.0, + 1.0000, 0.2604, 0.0, + 1.0000, 0.2708, 0.0, + 1.0000, 0.2812, 0.0, + 1.0000, 0.2917, 0.0, + 1.0000, 0.3021, 0.0, + 1.0000, 0.3125, 0.0, + 1.0000, 0.3229, 0.0, + 1.0000, 0.3333, 0.0, + 1.0000, 0.3438, 0.0, + 1.0000, 0.3542, 0.0, + 1.0000, 0.3646, 0.0, + 1.0000, 0.3750, 0.0, + 1.0000, 0.3854, 0.0, + 1.0000, 0.3958, 0.0, + 1.0000, 0.4062, 0.0, + 1.0000, 0.4167, 0.0, + 1.0000, 0.4271, 0.0, + 1.0000, 0.4375, 0.0, + 1.0000, 0.4479, 0.0, + 1.0000, 0.4583, 0.0, + 1.0000, 0.4688, 0.0, + 1.0000, 0.4792, 0.0, + 1.0000, 0.4896, 0.0, + 1.0000, 0.5000, 0.0, + 1.0000, 0.5104, 0.0, + 1.0000, 0.5208, 0.0, + 1.0000, 0.5312, 0.0, + 1.0000, 0.5417, 0.0, + 1.0000, 0.5521, 0.0, + 1.0000, 0.5625, 0.0, + 1.0000, 0.5729, 0.0, + 1.0000, 0.5833, 0.0, + 1.0000, 0.5938, 0.0, + 1.0000, 0.6042, 0.0, + 1.0000, 0.6146, 0.0, + 1.0000, 0.6250, 0.0, + 1.0000, 0.6354, 0.0, + 1.0000, 0.6458, 0.0, + 1.0000, 0.6562, 0.0, + 1.0000, 0.6667, 0.0, + 1.0000, 0.6771, 0.0, + 1.0000, 0.6875, 0.0, + 1.0000, 0.6979, 0.0, + 1.0000, 0.7083, 0.0, + 1.0000, 0.7188, 0.0, + 1.0000, 0.7292, 0.0, + 1.0000, 0.7396, 0.0, + 1.0000, 0.7500, 0.0, + 1.0000, 0.7604, 0.0, + 1.0000, 0.7708, 0.0, + 1.0000, 0.7812, 0.0, + 1.0000, 0.7917, 0.0, + 1.0000, 0.8021, 0.0, + 1.0000, 0.8125, 0.0, + 1.0000, 0.8229, 0.0, + 1.0000, 0.8333, 0.0, + 1.0000, 0.8438, 0.0, + 1.0000, 0.8542, 0.0, + 1.0000, 0.8646, 0.0, + 1.0000, 0.8750, 0.0, + 1.0000, 0.8854, 0.0, + 1.0000, 0.8958, 0.0, + 1.0000, 0.9062, 0.0, + 1.0000, 0.9167, 0.0, + 1.0000, 0.9271, 0.0, + 1.0000, 0.9375, 0.0, + 1.0000, 0.9479, 0.0, + 1.0000, 0.9583, 0.0, + 1.0000, 0.9688, 0.0, + 1.0000, 0.9792, 0.0, + 1.0000, 0.9896, 0.0, + 1.0000, 1.0000, 0.0, + 1.0000, 1.0000, 0.0156, + 1.0000, 1.0000, 0.0312, + 1.0000, 1.0000, 0.0469, + 1.0000, 1.0000, 0.0625, + 1.0000, 1.0000, 0.0781, + 1.0000, 1.0000, 0.0938, + 1.0000, 1.0000, 0.1094, + 1.0000, 1.0000, 0.1250, + 1.0000, 1.0000, 0.1406, + 1.0000, 1.0000, 0.1562, + 1.0000, 1.0000, 0.1719, + 1.0000, 1.0000, 0.1875, + 1.0000, 1.0000, 0.2031, + 1.0000, 1.0000, 0.2188, + 1.0000, 1.0000, 0.2344, + 1.0000, 1.0000, 0.2500, + 1.0000, 1.0000, 0.2656, + 1.0000, 1.0000, 0.2812, + 1.0000, 1.0000, 0.2969, + 1.0000, 1.0000, 0.3125, + 1.0000, 1.0000, 0.3281, + 1.0000, 1.0000, 0.3438, + 1.0000, 1.0000, 0.3594, + 1.0000, 1.0000, 0.3750, + 1.0000, 1.0000, 0.3906, + 1.0000, 1.0000, 0.4062, + 1.0000, 1.0000, 0.4219, + 1.0000, 1.0000, 0.4375, + 1.0000, 1.0000, 0.4531, + 1.0000, 1.0000, 0.4688, + 1.0000, 1.0000, 0.4844, + 1.0000, 1.0000, 0.5000, + 1.0000, 1.0000, 0.5156, + 1.0000, 1.0000, 0.5312, + 1.0000, 1.0000, 0.5469, + 1.0000, 1.0000, 0.5625, + 1.0000, 1.0000, 0.5781, + 1.0000, 1.0000, 0.5938, + 1.0000, 1.0000, 0.6094, + 1.0000, 1.0000, 0.6250, + 1.0000, 1.0000, 0.6406, + 1.0000, 1.0000, 0.6562, + 1.0000, 1.0000, 0.6719, + 1.0000, 1.0000, 0.6875, + 1.0000, 1.0000, 0.7031, + 1.0000, 1.0000, 0.7188, + 1.0000, 1.0000, 0.7344, + 1.0000, 1.0000, 0.7500, + 1.0000, 1.0000, 0.7656, + 1.0000, 1.0000, 0.7812, + 1.0000, 1.0000, 0.7969, + 1.0000, 1.0000, 0.8125, + 1.0000, 1.0000, 0.8281, + 1.0000, 1.0000, 0.8438, + 1.0000, 1.0000, 0.8594, + 1.0000, 1.0000, 0.8750, + 1.0000, 1.0000, 0.8906, + 1.0000, 1.0000, 0.9062, + 1.0000, 1.0000, 0.9219, + 1.0000, 1.0000, 0.9375, + 1.0000, 1.0000, 0.9531, + 1.0000, 1.0000, 0.9688, + 1.0000, 1.0000, 0.9844, + 1.0000, 1.0000, 1.0000, +}; + +const float ColorMap::m_cool[m_size] = +{ + 0.0, 1.0000, 1.0000, + 0.0039, 0.9961, 1.0000, + 0.0078, 0.9922, 1.0000, + 0.0118, 0.9882, 1.0000, + 0.0157, 0.9843, 1.0000, + 0.0196, 0.9804, 1.0000, + 0.0235, 0.9765, 1.0000, + 0.0275, 0.9725, 1.0000, + 0.0314, 0.9686, 1.0000, + 0.0353, 0.9647, 1.0000, + 0.0392, 0.9608, 1.0000, + 0.0431, 0.9569, 1.0000, + 0.0471, 0.9529, 1.0000, + 0.0510, 0.9490, 1.0000, + 0.0549, 0.9451, 1.0000, + 0.0588, 0.9412, 1.0000, + 0.0627, 0.9373, 1.0000, + 0.0667, 0.9333, 1.0000, + 0.0706, 0.9294, 1.0000, + 0.0745, 0.9255, 1.0000, + 0.0784, 0.9216, 1.0000, + 0.0824, 0.9176, 1.0000, + 0.0863, 0.9137, 1.0000, + 0.0902, 0.9098, 1.0000, + 0.0941, 0.9059, 1.0000, + 0.0980, 0.9020, 1.0000, + 0.1020, 0.8980, 1.0000, + 0.1059, 0.8941, 1.0000, + 0.1098, 0.8902, 1.0000, + 0.1137, 0.8863, 1.0000, + 0.1176, 0.8824, 1.0000, + 0.1216, 0.8784, 1.0000, + 0.1255, 0.8745, 1.0000, + 0.1294, 0.8706, 1.0000, + 0.1333, 0.8667, 1.0000, + 0.1373, 0.8627, 1.0000, + 0.1412, 0.8588, 1.0000, + 0.1451, 0.8549, 1.0000, + 0.1490, 0.8510, 1.0000, + 0.1529, 0.8471, 1.0000, + 0.1569, 0.8431, 1.0000, + 0.1608, 0.8392, 1.0000, + 0.1647, 0.8353, 1.0000, + 0.1686, 0.8314, 1.0000, + 0.1725, 0.8275, 1.0000, + 0.1765, 0.8235, 1.0000, + 0.1804, 0.8196, 1.0000, + 0.1843, 0.8157, 1.0000, + 0.1882, 0.8118, 1.0000, + 0.1922, 0.8078, 1.0000, + 0.1961, 0.8039, 1.0000, + 0.2000, 0.8000, 1.0000, + 0.2039, 0.7961, 1.0000, + 0.2078, 0.7922, 1.0000, + 0.2118, 0.7882, 1.0000, + 0.2157, 0.7843, 1.0000, + 0.2196, 0.7804, 1.0000, + 0.2235, 0.7765, 1.0000, + 0.2275, 0.7725, 1.0000, + 0.2314, 0.7686, 1.0000, + 0.2353, 0.7647, 1.0000, + 0.2392, 0.7608, 1.0000, + 0.2431, 0.7569, 1.0000, + 0.2471, 0.7529, 1.0000, + 0.2510, 0.7490, 1.0000, + 0.2549, 0.7451, 1.0000, + 0.2588, 0.7412, 1.0000, + 0.2627, 0.7373, 1.0000, + 0.2667, 0.7333, 1.0000, + 0.2706, 0.7294, 1.0000, + 0.2745, 0.7255, 1.0000, + 0.2784, 0.7216, 1.0000, + 0.2824, 0.7176, 1.0000, + 0.2863, 0.7137, 1.0000, + 0.2902, 0.7098, 1.0000, + 0.2941, 0.7059, 1.0000, + 0.2980, 0.7020, 1.0000, + 0.3020, 0.6980, 1.0000, + 0.3059, 0.6941, 1.0000, + 0.3098, 0.6902, 1.0000, + 0.3137, 0.6863, 1.0000, + 0.3176, 0.6824, 1.0000, + 0.3216, 0.6784, 1.0000, + 0.3255, 0.6745, 1.0000, + 0.3294, 0.6706, 1.0000, + 0.3333, 0.6667, 1.0000, + 0.3373, 0.6627, 1.0000, + 0.3412, 0.6588, 1.0000, + 0.3451, 0.6549, 1.0000, + 0.3490, 0.6510, 1.0000, + 0.3529, 0.6471, 1.0000, + 0.3569, 0.6431, 1.0000, + 0.3608, 0.6392, 1.0000, + 0.3647, 0.6353, 1.0000, + 0.3686, 0.6314, 1.0000, + 0.3725, 0.6275, 1.0000, + 0.3765, 0.6235, 1.0000, + 0.3804, 0.6196, 1.0000, + 0.3843, 0.6157, 1.0000, + 0.3882, 0.6118, 1.0000, + 0.3922, 0.6078, 1.0000, + 0.3961, 0.6039, 1.0000, + 0.4000, 0.6000, 1.0000, + 0.4039, 0.5961, 1.0000, + 0.4078, 0.5922, 1.0000, + 0.4118, 0.5882, 1.0000, + 0.4157, 0.5843, 1.0000, + 0.4196, 0.5804, 1.0000, + 0.4235, 0.5765, 1.0000, + 0.4275, 0.5725, 1.0000, + 0.4314, 0.5686, 1.0000, + 0.4353, 0.5647, 1.0000, + 0.4392, 0.5608, 1.0000, + 0.4431, 0.5569, 1.0000, + 0.4471, 0.5529, 1.0000, + 0.4510, 0.5490, 1.0000, + 0.4549, 0.5451, 1.0000, + 0.4588, 0.5412, 1.0000, + 0.4627, 0.5373, 1.0000, + 0.4667, 0.5333, 1.0000, + 0.4706, 0.5294, 1.0000, + 0.4745, 0.5255, 1.0000, + 0.4784, 0.5216, 1.0000, + 0.4824, 0.5176, 1.0000, + 0.4863, 0.5137, 1.0000, + 0.4902, 0.5098, 1.0000, + 0.4941, 0.5059, 1.0000, + 0.4980, 0.5020, 1.0000, + 0.5020, 0.4980, 1.0000, + 0.5059, 0.4941, 1.0000, + 0.5098, 0.4902, 1.0000, + 0.5137, 0.4863, 1.0000, + 0.5176, 0.4824, 1.0000, + 0.5216, 0.4784, 1.0000, + 0.5255, 0.4745, 1.0000, + 0.5294, 0.4706, 1.0000, + 0.5333, 0.4667, 1.0000, + 0.5373, 0.4627, 1.0000, + 0.5412, 0.4588, 1.0000, + 0.5451, 0.4549, 1.0000, + 0.5490, 0.4510, 1.0000, + 0.5529, 0.4471, 1.0000, + 0.5569, 0.4431, 1.0000, + 0.5608, 0.4392, 1.0000, + 0.5647, 0.4353, 1.0000, + 0.5686, 0.4314, 1.0000, + 0.5725, 0.4275, 1.0000, + 0.5765, 0.4235, 1.0000, + 0.5804, 0.4196, 1.0000, + 0.5843, 0.4157, 1.0000, + 0.5882, 0.4118, 1.0000, + 0.5922, 0.4078, 1.0000, + 0.5961, 0.4039, 1.0000, + 0.6000, 0.4000, 1.0000, + 0.6039, 0.3961, 1.0000, + 0.6078, 0.3922, 1.0000, + 0.6118, 0.3882, 1.0000, + 0.6157, 0.3843, 1.0000, + 0.6196, 0.3804, 1.0000, + 0.6235, 0.3765, 1.0000, + 0.6275, 0.3725, 1.0000, + 0.6314, 0.3686, 1.0000, + 0.6353, 0.3647, 1.0000, + 0.6392, 0.3608, 1.0000, + 0.6431, 0.3569, 1.0000, + 0.6471, 0.3529, 1.0000, + 0.6510, 0.3490, 1.0000, + 0.6549, 0.3451, 1.0000, + 0.6588, 0.3412, 1.0000, + 0.6627, 0.3373, 1.0000, + 0.6667, 0.3333, 1.0000, + 0.6706, 0.3294, 1.0000, + 0.6745, 0.3255, 1.0000, + 0.6784, 0.3216, 1.0000, + 0.6824, 0.3176, 1.0000, + 0.6863, 0.3137, 1.0000, + 0.6902, 0.3098, 1.0000, + 0.6941, 0.3059, 1.0000, + 0.6980, 0.3020, 1.0000, + 0.7020, 0.2980, 1.0000, + 0.7059, 0.2941, 1.0000, + 0.7098, 0.2902, 1.0000, + 0.7137, 0.2863, 1.0000, + 0.7176, 0.2824, 1.0000, + 0.7216, 0.2784, 1.0000, + 0.7255, 0.2745, 1.0000, + 0.7294, 0.2706, 1.0000, + 0.7333, 0.2667, 1.0000, + 0.7373, 0.2627, 1.0000, + 0.7412, 0.2588, 1.0000, + 0.7451, 0.2549, 1.0000, + 0.7490, 0.2510, 1.0000, + 0.7529, 0.2471, 1.0000, + 0.7569, 0.2431, 1.0000, + 0.7608, 0.2392, 1.0000, + 0.7647, 0.2353, 1.0000, + 0.7686, 0.2314, 1.0000, + 0.7725, 0.2275, 1.0000, + 0.7765, 0.2235, 1.0000, + 0.7804, 0.2196, 1.0000, + 0.7843, 0.2157, 1.0000, + 0.7882, 0.2118, 1.0000, + 0.7922, 0.2078, 1.0000, + 0.7961, 0.2039, 1.0000, + 0.8000, 0.2000, 1.0000, + 0.8039, 0.1961, 1.0000, + 0.8078, 0.1922, 1.0000, + 0.8118, 0.1882, 1.0000, + 0.8157, 0.1843, 1.0000, + 0.8196, 0.1804, 1.0000, + 0.8235, 0.1765, 1.0000, + 0.8275, 0.1725, 1.0000, + 0.8314, 0.1686, 1.0000, + 0.8353, 0.1647, 1.0000, + 0.8392, 0.1608, 1.0000, + 0.8431, 0.1569, 1.0000, + 0.8471, 0.1529, 1.0000, + 0.8510, 0.1490, 1.0000, + 0.8549, 0.1451, 1.0000, + 0.8588, 0.1412, 1.0000, + 0.8627, 0.1373, 1.0000, + 0.8667, 0.1333, 1.0000, + 0.8706, 0.1294, 1.0000, + 0.8745, 0.1255, 1.0000, + 0.8784, 0.1216, 1.0000, + 0.8824, 0.1176, 1.0000, + 0.8863, 0.1137, 1.0000, + 0.8902, 0.1098, 1.0000, + 0.8941, 0.1059, 1.0000, + 0.8980, 0.1020, 1.0000, + 0.9020, 0.0980, 1.0000, + 0.9059, 0.0941, 1.0000, + 0.9098, 0.0902, 1.0000, + 0.9137, 0.0863, 1.0000, + 0.9176, 0.0824, 1.0000, + 0.9216, 0.0784, 1.0000, + 0.9255, 0.0745, 1.0000, + 0.9294, 0.0706, 1.0000, + 0.9333, 0.0667, 1.0000, + 0.9373, 0.0627, 1.0000, + 0.9412, 0.0588, 1.0000, + 0.9451, 0.0549, 1.0000, + 0.9490, 0.0510, 1.0000, + 0.9529, 0.0471, 1.0000, + 0.9569, 0.0431, 1.0000, + 0.9608, 0.0392, 1.0000, + 0.9647, 0.0353, 1.0000, + 0.9686, 0.0314, 1.0000, + 0.9725, 0.0275, 1.0000, + 0.9765, 0.0235, 1.0000, + 0.9804, 0.0196, 1.0000, + 0.9843, 0.0157, 1.0000, + 0.9882, 0.0118, 1.0000, + 0.9922, 0.0078, 1.0000, + 0.9961, 0.0039, 1.0000, + 1.0000, 0.0, 1.0000, +}; + +const float ColorMap::m_batlow[m_size] = +{ + 0.005193, 0.098238, 0.349842, + 0.009065, 0.104487, 0.350933, + 0.012963, 0.110779, 0.351992, + 0.016530, 0.116913, 0.353070, + 0.019936, 0.122985, 0.354120, + 0.023189, 0.129035, 0.355182, + 0.026291, 0.135044, 0.356210, + 0.029245, 0.140964, 0.357239, + 0.032053, 0.146774, 0.358239, + 0.034853, 0.152558, 0.359233, + 0.037449, 0.158313, 0.360216, + 0.039845, 0.163978, 0.361187, + 0.042104, 0.169557, 0.362151, + 0.044069, 0.175053, 0.363084, + 0.045905, 0.180460, 0.364007, + 0.047665, 0.185844, 0.364915, + 0.049378, 0.191076, 0.365810, + 0.050795, 0.196274, 0.366684, + 0.052164, 0.201323, 0.367524, + 0.053471, 0.206357, 0.368370, + 0.054721, 0.211234, 0.369184, + 0.055928, 0.216046, 0.369974, + 0.057033, 0.220754, 0.370750, + 0.058032, 0.225340, 0.371509, + 0.059164, 0.229842, 0.372252, + 0.060167, 0.234299, 0.372978, + 0.061052, 0.238625, 0.373691, + 0.062060, 0.242888, 0.374386, + 0.063071, 0.247085, 0.375050, + 0.063982, 0.251213, 0.375709, + 0.064936, 0.255264, 0.376362, + 0.065903, 0.259257, 0.376987, + 0.066899, 0.263188, 0.377594, + 0.067921, 0.267056, 0.378191, + 0.069002, 0.270922, 0.378774, + 0.070001, 0.274713, 0.379342, + 0.071115, 0.278497, 0.379895, + 0.072192, 0.282249, 0.380434, + 0.073440, 0.285942, 0.380957, + 0.074595, 0.289653, 0.381452, + 0.075833, 0.293321, 0.381922, + 0.077136, 0.296996, 0.382376, + 0.078517, 0.300622, 0.382814, + 0.079984, 0.304252, 0.383224, + 0.081553, 0.307858, 0.383598, + 0.083082, 0.311461, 0.383936, + 0.084778, 0.315043, 0.384240, + 0.086503, 0.318615, 0.384506, + 0.088353, 0.322167, 0.384731, + 0.090281, 0.325685, 0.384910, + 0.092304, 0.329220, 0.385040, + 0.094462, 0.332712, 0.385116, + 0.096618, 0.336161, 0.385134, + 0.099015, 0.339621, 0.385090, + 0.101481, 0.343036, 0.384981, + 0.104078, 0.346410, 0.384801, + 0.106842, 0.349774, 0.384548, + 0.109695, 0.353098, 0.384217, + 0.112655, 0.356391, 0.383807, + 0.115748, 0.359638, 0.383310, + 0.118992, 0.362849, 0.382713, + 0.122320, 0.366030, 0.382026, + 0.125889, 0.369160, 0.381259, + 0.129519, 0.372238, 0.380378, + 0.133298, 0.375282, 0.379395, + 0.137212, 0.378282, 0.378315, + 0.141260, 0.381240, 0.377135, + 0.145432, 0.384130, 0.375840, + 0.149706, 0.386975, 0.374449, + 0.154073, 0.389777, 0.372934, + 0.158620, 0.392531, 0.371320, + 0.163246, 0.395237, 0.369609, + 0.167952, 0.397889, 0.367784, + 0.172788, 0.400496, 0.365867, + 0.177752, 0.403041, 0.363833, + 0.182732, 0.405551, 0.361714, + 0.187886, 0.408003, 0.359484, + 0.193050, 0.410427, 0.357177, + 0.198310, 0.412798, 0.354767, + 0.203676, 0.415116, 0.352253, + 0.209075, 0.417412, 0.349677, + 0.214555, 0.419661, 0.347019, + 0.220112, 0.421864, 0.344261, + 0.225707, 0.424049, 0.341459, + 0.231362, 0.426197, 0.338572, + 0.237075, 0.428325, 0.335634, + 0.242795, 0.430418, 0.332635, + 0.248617, 0.432493, 0.329571, + 0.254452, 0.434529, 0.326434, + 0.260320, 0.436556, 0.323285, + 0.266241, 0.438555, 0.320085, + 0.272168, 0.440541, 0.316831, + 0.278171, 0.442524, 0.313552, + 0.284175, 0.444484, 0.310243, + 0.290214, 0.446420, 0.306889, + 0.296294, 0.448357, 0.303509, + 0.302379, 0.450282, 0.300122, + 0.308517, 0.452205, 0.296721, + 0.314648, 0.454107, 0.293279, + 0.320834, 0.456006, 0.289841, + 0.327007, 0.457900, 0.286377, + 0.333235, 0.459794, 0.282937, + 0.339469, 0.461685, 0.279468, + 0.345703, 0.463563, 0.275998, + 0.351976, 0.465440, 0.272492, + 0.358277, 0.467331, 0.269037, + 0.364589, 0.469213, 0.265543, + 0.370922, 0.471085, 0.262064, + 0.377291, 0.472952, 0.258588, + 0.383675, 0.474842, 0.255131, + 0.390070, 0.476711, 0.251665, + 0.396505, 0.478587, 0.248212, + 0.402968, 0.480466, 0.244731, + 0.409455, 0.482351, 0.241314, + 0.415967, 0.484225, 0.237895, + 0.422507, 0.486113, 0.234493, + 0.429094, 0.488011, 0.231096, + 0.435714, 0.489890, 0.227728, + 0.442365, 0.491795, 0.224354, + 0.449052, 0.493684, 0.221074, + 0.455774, 0.495585, 0.217774, + 0.462539, 0.497497, 0.214518, + 0.469368, 0.499393, 0.211318, + 0.476221, 0.501314, 0.208148, + 0.483123, 0.503216, 0.205037, + 0.490081, 0.505137, 0.201976, + 0.497089, 0.507058, 0.198994, + 0.504153, 0.508984, 0.196118, + 0.511253, 0.510898, 0.193296, + 0.518425, 0.512822, 0.190566, + 0.525637, 0.514746, 0.187990, + 0.532907, 0.516662, 0.185497, + 0.540225, 0.518584, 0.183099, + 0.547599, 0.520486, 0.180884, + 0.555024, 0.522391, 0.178854, + 0.562506, 0.524293, 0.176964, + 0.570016, 0.526186, 0.175273, + 0.577582, 0.528058, 0.173775, + 0.585199, 0.529927, 0.172493, + 0.592846, 0.531777, 0.171449, + 0.600520, 0.533605, 0.170648, + 0.608240, 0.535423, 0.170104, + 0.615972, 0.537231, 0.169826, + 0.623739, 0.539002, 0.169814, + 0.631513, 0.540752, 0.170075, + 0.639301, 0.542484, 0.170622, + 0.647098, 0.544183, 0.171465, + 0.654889, 0.545863, 0.172603, + 0.662691, 0.547503, 0.174044, + 0.670477, 0.549127, 0.175747, + 0.678244, 0.550712, 0.177803, + 0.685995, 0.552274, 0.180056, + 0.693720, 0.553797, 0.182610, + 0.701421, 0.555294, 0.185478, + 0.709098, 0.556772, 0.188546, + 0.716731, 0.558205, 0.191851, + 0.724322, 0.559628, 0.195408, + 0.731878, 0.561011, 0.199174, + 0.739393, 0.562386, 0.203179, + 0.746850, 0.563725, 0.207375, + 0.754268, 0.565033, 0.211761, + 0.761629, 0.566344, 0.216322, + 0.768942, 0.567630, 0.221045, + 0.776208, 0.568899, 0.225930, + 0.783416, 0.570162, 0.230962, + 0.790568, 0.571421, 0.236160, + 0.797665, 0.572682, 0.241490, + 0.804709, 0.573928, 0.246955, + 0.811692, 0.575187, 0.252572, + 0.818610, 0.576462, 0.258303, + 0.825472, 0.577725, 0.264197, + 0.832272, 0.579026, 0.270211, + 0.838999, 0.580339, 0.276353, + 0.845657, 0.581672, 0.282631, + 0.852247, 0.583037, 0.289036, + 0.858747, 0.584440, 0.295572, + 0.865168, 0.585882, 0.302255, + 0.871505, 0.587352, 0.309112, + 0.877741, 0.588873, 0.316081, + 0.883878, 0.590450, 0.323195, + 0.889900, 0.592087, 0.330454, + 0.895809, 0.593765, 0.337865, + 0.901590, 0.595507, 0.345429, + 0.907242, 0.597319, 0.353142, + 0.912746, 0.599191, 0.360986, + 0.918103, 0.601126, 0.368999, + 0.923300, 0.603137, 0.377139, + 0.928323, 0.605212, 0.385404, + 0.933176, 0.607369, 0.393817, + 0.937850, 0.609582, 0.402345, + 0.942332, 0.611867, 0.411006, + 0.946612, 0.614218, 0.419767, + 0.950697, 0.616649, 0.428624, + 0.954574, 0.619137, 0.437582, + 0.958244, 0.621671, 0.446604, + 0.961696, 0.624282, 0.455702, + 0.964943, 0.626934, 0.464860, + 0.967983, 0.629639, 0.474057, + 0.970804, 0.632394, 0.483290, + 0.973424, 0.635183, 0.492547, + 0.975835, 0.638012, 0.501826, + 0.978052, 0.640868, 0.511090, + 0.980079, 0.643752, 0.520350, + 0.981918, 0.646664, 0.529602, + 0.983574, 0.649590, 0.538819, + 0.985066, 0.652522, 0.547998, + 0.986392, 0.655470, 0.557142, + 0.987567, 0.658422, 0.566226, + 0.988596, 0.661378, 0.575265, + 0.989496, 0.664329, 0.584246, + 0.990268, 0.667280, 0.593174, + 0.990926, 0.670230, 0.602031, + 0.991479, 0.673165, 0.610835, + 0.991935, 0.676091, 0.619575, + 0.992305, 0.679007, 0.628251, + 0.992595, 0.681914, 0.636869, + 0.992813, 0.684815, 0.645423, + 0.992967, 0.687705, 0.653934, + 0.993064, 0.690579, 0.662398, + 0.993111, 0.693451, 0.670810, + 0.993112, 0.696314, 0.679177, + 0.993074, 0.699161, 0.687519, + 0.993002, 0.702006, 0.695831, + 0.992900, 0.704852, 0.704114, + 0.992771, 0.707689, 0.712380, + 0.992619, 0.710530, 0.720639, + 0.992447, 0.713366, 0.728892, + 0.992258, 0.716210, 0.737146, + 0.992054, 0.719049, 0.745403, + 0.991837, 0.721893, 0.753673, + 0.991607, 0.724754, 0.761959, + 0.991367, 0.727614, 0.770270, + 0.991116, 0.730489, 0.778606, + 0.990855, 0.733373, 0.786976, + 0.990586, 0.736265, 0.795371, + 0.990307, 0.739184, 0.803810, + 0.990018, 0.742102, 0.812285, + 0.989720, 0.745039, 0.820804, + 0.989411, 0.747997, 0.829372, + 0.989089, 0.750968, 0.837979, + 0.988754, 0.753949, 0.846627, + 0.988406, 0.756949, 0.855332, + 0.988046, 0.759964, 0.864078, + 0.987672, 0.762996, 0.872864, + 0.987280, 0.766047, 0.881699, + 0.986868, 0.769105, 0.890573, + 0.986435, 0.772184, 0.899493, + 0.985980, 0.775272, 0.908448, + 0.985503, 0.778378, 0.917444, + 0.985002, 0.781495, 0.926468, + 0.984473, 0.784624, 0.935531, + 0.983913, 0.787757, 0.944626, + 0.983322, 0.790905, 0.953748, + 0.982703, 0.794068, 0.962895, + 0.982048, 0.797228, 0.972070, + 0.981354, 0.800406, 0.981267 +}; + +const float ColorMap::m_hawaii[m_size] = +{ + 0.550541, 0.006842, 0.451980, + 0.551494, 0.015367, 0.447972, + 0.552426, 0.023795, 0.443998, + 0.553328, 0.032329, 0.440021, + 0.554227, 0.041170, 0.436063, + 0.555098, 0.049286, 0.432125, + 0.555948, 0.056667, 0.428188, + 0.556797, 0.063525, 0.424272, + 0.557619, 0.069970, 0.420377, + 0.558415, 0.076028, 0.416509, + 0.559210, 0.081936, 0.412663, + 0.559991, 0.087507, 0.408823, + 0.560746, 0.092811, 0.405012, + 0.561495, 0.098081, 0.401237, + 0.562235, 0.103128, 0.397471, + 0.562954, 0.108005, 0.393736, + 0.563663, 0.112872, 0.390025, + 0.564355, 0.117530, 0.386344, + 0.565032, 0.122122, 0.382698, + 0.565709, 0.126681, 0.379074, + 0.566380, 0.131171, 0.375474, + 0.567037, 0.135542, 0.371905, + 0.567679, 0.139872, 0.368378, + 0.568312, 0.144198, 0.364861, + 0.568939, 0.148416, 0.361384, + 0.569559, 0.152618, 0.357942, + 0.570171, 0.156806, 0.354519, + 0.570777, 0.160934, 0.351127, + 0.571377, 0.165008, 0.347764, + 0.571972, 0.169120, 0.344417, + 0.572562, 0.173131, 0.341120, + 0.573142, 0.177166, 0.337836, + 0.573711, 0.181138, 0.334602, + 0.574276, 0.185151, 0.331356, + 0.574840, 0.189095, 0.328170, + 0.575406, 0.193035, 0.324992, + 0.575967, 0.196978, 0.321854, + 0.576518, 0.200854, 0.318740, + 0.577060, 0.204783, 0.315654, + 0.577596, 0.208664, 0.312565, + 0.578135, 0.212545, 0.309542, + 0.578676, 0.216431, 0.306516, + 0.579214, 0.220287, 0.303496, + 0.579746, 0.224106, 0.300518, + 0.580271, 0.227977, 0.297566, + 0.580793, 0.231817, 0.294618, + 0.581315, 0.235646, 0.291715, + 0.581835, 0.239463, 0.288810, + 0.582353, 0.243268, 0.285910, + 0.582870, 0.247097, 0.283066, + 0.583386, 0.250916, 0.280201, + 0.583901, 0.254739, 0.277381, + 0.584416, 0.258531, 0.274552, + 0.584931, 0.262342, 0.271740, + 0.585443, 0.266156, 0.268980, + 0.585951, 0.269966, 0.266198, + 0.586456, 0.273771, 0.263439, + 0.586961, 0.277575, 0.260676, + 0.587466, 0.281374, 0.257925, + 0.587972, 0.285180, 0.255221, + 0.588478, 0.289013, 0.252494, + 0.588984, 0.292818, 0.249767, + 0.589491, 0.296652, 0.247081, + 0.589999, 0.300465, 0.244376, + 0.590507, 0.304300, 0.241716, + 0.591016, 0.308135, 0.239031, + 0.591526, 0.311969, 0.236379, + 0.592038, 0.315846, 0.233692, + 0.592548, 0.319698, 0.231058, + 0.593055, 0.323559, 0.228420, + 0.593562, 0.327429, 0.225773, + 0.594071, 0.331309, 0.223134, + 0.594583, 0.335229, 0.220510, + 0.595095, 0.339131, 0.217865, + 0.595609, 0.343048, 0.215226, + 0.596126, 0.346976, 0.212613, + 0.596645, 0.350921, 0.209994, + 0.597164, 0.354880, 0.207388, + 0.597680, 0.358830, 0.204776, + 0.598196, 0.362821, 0.202147, + 0.598721, 0.366829, 0.199533, + 0.599248, 0.370837, 0.196964, + 0.599771, 0.374879, 0.194370, + 0.600294, 0.378931, 0.191738, + 0.600819, 0.383009, 0.189149, + 0.601346, 0.387090, 0.186548, + 0.601874, 0.391215, 0.183949, + 0.602403, 0.395345, 0.181345, + 0.602933, 0.399486, 0.178782, + 0.603464, 0.403678, 0.176158, + 0.603995, 0.407873, 0.173594, + 0.604521, 0.412102, 0.171015, + 0.605043, 0.416348, 0.168436, + 0.605562, 0.420618, 0.165848, + 0.606084, 0.424928, 0.163317, + 0.606609, 0.429252, 0.160731, + 0.607129, 0.433600, 0.158195, + 0.607639, 0.437998, 0.155649, + 0.608144, 0.442412, 0.153086, + 0.608644, 0.446848, 0.150582, + 0.609134, 0.451324, 0.148071, + 0.609610, 0.455826, 0.145615, + 0.610079, 0.460356, 0.143119, + 0.610542, 0.464933, 0.140685, + 0.610991, 0.469544, 0.138267, + 0.611421, 0.474170, 0.135829, + 0.611833, 0.478839, 0.133514, + 0.612226, 0.483539, 0.131212, + 0.612600, 0.488287, 0.128920, + 0.612950, 0.493049, 0.126718, + 0.613275, 0.497875, 0.124574, + 0.613572, 0.502705, 0.122487, + 0.613837, 0.507592, 0.120512, + 0.614069, 0.512502, 0.118669, + 0.614264, 0.517459, 0.116848, + 0.614418, 0.522434, 0.115160, + 0.614530, 0.527456, 0.113657, + 0.614594, 0.532510, 0.112266, + 0.614607, 0.537595, 0.111032, + 0.614566, 0.542708, 0.109999, + 0.614468, 0.547849, 0.109114, + 0.614308, 0.553016, 0.108421, + 0.614082, 0.558212, 0.108010, + 0.613787, 0.563446, 0.107850, + 0.613419, 0.568682, 0.107943, + 0.612974, 0.573946, 0.108312, + 0.612449, 0.579232, 0.109026, + 0.611842, 0.584522, 0.110040, + 0.611148, 0.589820, 0.111320, + 0.610353, 0.595132, 0.112963, + 0.609471, 0.600443, 0.114856, + 0.608494, 0.605748, 0.117169, + 0.607411, 0.611060, 0.119811, + 0.606215, 0.616350, 0.122763, + 0.604930, 0.621618, 0.126124, + 0.603536, 0.626876, 0.129757, + 0.602026, 0.632107, 0.133692, + 0.600413, 0.637306, 0.137967, + 0.598689, 0.642469, 0.142496, + 0.596862, 0.647588, 0.147334, + 0.594916, 0.652662, 0.152416, + 0.592872, 0.657697, 0.157790, + 0.590707, 0.662667, 0.163419, + 0.588441, 0.667579, 0.169258, + 0.586085, 0.672429, 0.175280, + 0.583613, 0.677213, 0.181507, + 0.581049, 0.681916, 0.187985, + 0.578388, 0.686560, 0.194586, + 0.575646, 0.691121, 0.201310, + 0.572809, 0.695614, 0.208243, + 0.569878, 0.700018, 0.215285, + 0.566888, 0.704346, 0.222470, + 0.563814, 0.708597, 0.229738, + 0.560662, 0.712753, 0.237171, + 0.557458, 0.716845, 0.244622, + 0.554182, 0.720839, 0.252219, + 0.550853, 0.724766, 0.259874, + 0.547470, 0.728605, 0.267574, + 0.544043, 0.732376, 0.275394, + 0.540571, 0.736058, 0.283238, + 0.537067, 0.739685, 0.291141, + 0.533507, 0.743228, 0.299094, + 0.529936, 0.746702, 0.307079, + 0.526333, 0.750112, 0.315113, + 0.522696, 0.753461, 0.323192, + 0.519049, 0.756752, 0.331281, + 0.515367, 0.759983, 0.339437, + 0.511681, 0.763162, 0.347595, + 0.507990, 0.766293, 0.355785, + 0.504280, 0.769372, 0.363984, + 0.500550, 0.772410, 0.372217, + 0.496820, 0.775405, 0.380485, + 0.493085, 0.778365, 0.388763, + 0.489350, 0.781287, 0.397049, + 0.485614, 0.784180, 0.405376, + 0.481884, 0.787038, 0.413711, + 0.478142, 0.789866, 0.422057, + 0.474411, 0.792674, 0.430440, + 0.470680, 0.795455, 0.438824, + 0.466955, 0.798219, 0.447235, + 0.463220, 0.800964, 0.455667, + 0.459518, 0.803693, 0.464121, + 0.455810, 0.806409, 0.472577, + 0.452124, 0.809110, 0.481054, + 0.448436, 0.811796, 0.489555, + 0.444772, 0.814472, 0.498091, + 0.441108, 0.817144, 0.506616, + 0.437487, 0.819803, 0.515175, + 0.433858, 0.822465, 0.523755, + 0.430280, 0.825110, 0.532352, + 0.426720, 0.827756, 0.540960, + 0.423186, 0.830401, 0.549598, + 0.419708, 0.833036, 0.558241, + 0.416257, 0.835673, 0.566923, + 0.412868, 0.838305, 0.575612, + 0.409520, 0.840937, 0.584314, + 0.406245, 0.843562, 0.593044, + 0.403035, 0.846190, 0.601780, + 0.399905, 0.848819, 0.610541, + 0.396872, 0.851439, 0.619320, + 0.393950, 0.854061, 0.628104, + 0.391152, 0.856683, 0.636905, + 0.388472, 0.859301, 0.645709, + 0.385935, 0.861918, 0.654530, + 0.383585, 0.864526, 0.663367, + 0.381407, 0.867128, 0.672196, + 0.379424, 0.869728, 0.681023, + 0.377672, 0.872325, 0.689863, + 0.376170, 0.874907, 0.698686, + 0.374923, 0.877482, 0.707507, + 0.373981, 0.880045, 0.716318, + 0.373340, 0.882596, 0.725106, + 0.373043, 0.885136, 0.733865, + 0.373112, 0.887654, 0.742601, + 0.373570, 0.890156, 0.751300, + 0.374439, 0.892639, 0.759946, + 0.375723, 0.895095, 0.768546, + 0.377467, 0.897524, 0.777098, + 0.379671, 0.899923, 0.785572, + 0.382352, 0.902288, 0.793974, + 0.385527, 0.904619, 0.802283, + 0.389213, 0.906913, 0.810503, + 0.393385, 0.909161, 0.818619, + 0.398074, 0.911369, 0.826627, + 0.403255, 0.913528, 0.834507, + 0.408926, 0.915628, 0.842255, + 0.415083, 0.917688, 0.849859, + 0.421704, 0.919678, 0.857309, + 0.428791, 0.921615, 0.864606, + 0.436305, 0.923489, 0.871734, + 0.444231, 0.925293, 0.878682, + 0.452541, 0.927032, 0.885454, + 0.461203, 0.928705, 0.892037, + 0.470211, 0.930311, 0.898424, + 0.479521, 0.931839, 0.904620, + 0.489103, 0.933297, 0.910617, + 0.498950, 0.934685, 0.916408, + 0.509019, 0.936004, 0.922005, + 0.519281, 0.937246, 0.927394, + 0.529715, 0.938416, 0.932588, + 0.540292, 0.939517, 0.937592, + 0.550997, 0.940549, 0.942401, + 0.561804, 0.941509, 0.947020, + 0.572686, 0.942411, 0.951459, + 0.583621, 0.943243, 0.955728, + 0.594606, 0.944015, 0.959825, + 0.605610, 0.944731, 0.963765, + 0.616637, 0.945388, 0.967563, + 0.627648, 0.945989, 0.971214, + 0.638645, 0.946543, 0.974739, + 0.649620, 0.947052, 0.978146, + 0.660548, 0.947515, 0.981449, + 0.671439, 0.947934, 0.984653, + 0.682276, 0.948316, 0.987765, + 0.693064, 0.948662, 0.990803, + 0.703779, 0.948977, 0.993775, +}; + +const float ColorMap::m_acton[m_size] = +{ + 0.180627, 0.129916, 0.300244, + 0.184610, 0.133361, 0.303782, + 0.188588, 0.136829, 0.307330, + 0.192547, 0.140323, 0.310900, + 0.196548, 0.143832, 0.314443, + 0.200488, 0.147341, 0.318015, + 0.204515, 0.150846, 0.321581, + 0.208493, 0.154369, 0.325153, + 0.212499, 0.157916, 0.328752, + 0.216523, 0.161488, 0.332345, + 0.220543, 0.164997, 0.335928, + 0.224526, 0.168579, 0.339540, + 0.228599, 0.172138, 0.343143, + 0.232627, 0.175706, 0.346749, + 0.236700, 0.179309, 0.350370, + 0.240738, 0.182887, 0.353978, + 0.244814, 0.186502, 0.357622, + 0.248930, 0.190104, 0.361237, + 0.253030, 0.193733, 0.364873, + 0.257149, 0.197344, 0.368523, + 0.261278, 0.200942, 0.372155, + 0.265425, 0.204605, 0.375810, + 0.269603, 0.208226, 0.379461, + 0.273783, 0.211881, 0.383124, + 0.277979, 0.215505, 0.386769, + 0.282205, 0.219155, 0.390435, + 0.286418, 0.222807, 0.394097, + 0.290686, 0.226458, 0.397768, + 0.294964, 0.230077, 0.401431, + 0.299282, 0.233732, 0.405095, + 0.303592, 0.237416, 0.408762, + 0.307941, 0.241039, 0.412436, + 0.312311, 0.244675, 0.416090, + 0.316729, 0.248352, 0.419755, + 0.321155, 0.251983, 0.423403, + 0.325598, 0.255610, 0.427069, + 0.330097, 0.259251, 0.430713, + 0.334616, 0.262862, 0.434349, + 0.339156, 0.266474, 0.437993, + 0.343715, 0.270084, 0.441616, + 0.348325, 0.273673, 0.445226, + 0.352962, 0.277246, 0.448836, + 0.357638, 0.280787, 0.452429, + 0.362328, 0.284342, 0.455994, + 0.367058, 0.287868, 0.459557, + 0.371818, 0.291393, 0.463085, + 0.376633, 0.294861, 0.466617, + 0.381462, 0.298321, 0.470119, + 0.386314, 0.301752, 0.473581, + 0.391226, 0.305175, 0.477035, + 0.396151, 0.308549, 0.480453, + 0.401118, 0.311869, 0.483838, + 0.406106, 0.315187, 0.487202, + 0.411121, 0.318455, 0.490524, + 0.416168, 0.321674, 0.493799, + 0.421236, 0.324852, 0.497039, + 0.426337, 0.327992, 0.500233, + 0.431473, 0.331069, 0.503383, + 0.436612, 0.334121, 0.506490, + 0.441778, 0.337097, 0.509547, + 0.446951, 0.340021, 0.512544, + 0.452154, 0.342888, 0.515484, + 0.457349, 0.345672, 0.518381, + 0.462561, 0.348416, 0.521200, + 0.467788, 0.351091, 0.523965, + 0.473007, 0.353679, 0.526669, + 0.478238, 0.356221, 0.529300, + 0.483458, 0.358663, 0.531858, + 0.488682, 0.361046, 0.534347, + 0.493892, 0.363356, 0.536777, + 0.499089, 0.365589, 0.539117, + 0.504283, 0.367733, 0.541384, + 0.509444, 0.369805, 0.543590, + 0.514595, 0.371793, 0.545716, + 0.519714, 0.373712, 0.547758, + 0.524818, 0.375534, 0.549728, + 0.529895, 0.377288, 0.551623, + 0.534937, 0.378952, 0.553431, + 0.539948, 0.380544, 0.555173, + 0.544933, 0.382041, 0.556844, + 0.549880, 0.383480, 0.558423, + 0.554790, 0.384818, 0.559949, + 0.559666, 0.386090, 0.561388, + 0.564500, 0.387290, 0.562768, + 0.569294, 0.388425, 0.564070, + 0.574054, 0.389478, 0.565293, + 0.578778, 0.390463, 0.566473, + 0.583458, 0.391391, 0.567579, + 0.588099, 0.392240, 0.568620, + 0.592717, 0.393035, 0.569606, + 0.597284, 0.393772, 0.570538, + 0.601814, 0.394456, 0.571418, + 0.606313, 0.395091, 0.572252, + 0.610786, 0.395679, 0.573036, + 0.615216, 0.396214, 0.573769, + 0.619634, 0.396704, 0.574463, + 0.624015, 0.397168, 0.575129, + 0.628373, 0.397605, 0.575767, + 0.632707, 0.398012, 0.576370, + 0.637028, 0.398390, 0.576941, + 0.641325, 0.398748, 0.577490, + 0.645618, 0.399094, 0.578027, + 0.649908, 0.399435, 0.578559, + 0.654185, 0.399779, 0.579086, + 0.658464, 0.400135, 0.579609, + 0.662752, 0.400504, 0.580132, + 0.667036, 0.400885, 0.580663, + 0.671339, 0.401281, 0.581210, + 0.675658, 0.401708, 0.581780, + 0.679991, 0.402185, 0.582378, + 0.684352, 0.402720, 0.583011, + 0.688751, 0.403316, 0.583686, + 0.693170, 0.403970, 0.584410, + 0.697618, 0.404697, 0.585192, + 0.702109, 0.405530, 0.586030, + 0.706646, 0.406448, 0.586932, + 0.711216, 0.407470, 0.587915, + 0.715827, 0.408615, 0.588983, + 0.720469, 0.409892, 0.590145, + 0.725160, 0.411292, 0.591407, + 0.729876, 0.412855, 0.592772, + 0.734623, 0.414551, 0.594233, + 0.739395, 0.416419, 0.595813, + 0.744169, 0.418444, 0.597513, + 0.748950, 0.420648, 0.599331, + 0.753728, 0.423021, 0.601262, + 0.758484, 0.425579, 0.603322, + 0.763197, 0.428302, 0.605491, + 0.767861, 0.431199, 0.607790, + 0.772460, 0.434246, 0.610185, + 0.776977, 0.437474, 0.612689, + 0.781382, 0.440823, 0.615295, + 0.785670, 0.444338, 0.617993, + 0.789819, 0.447951, 0.620776, + 0.793821, 0.451698, 0.623624, + 0.797645, 0.455528, 0.626525, + 0.801296, 0.459445, 0.629480, + 0.804757, 0.463415, 0.632479, + 0.808016, 0.467455, 0.635498, + 0.811068, 0.471522, 0.638538, + 0.813906, 0.475607, 0.641580, + 0.816539, 0.479697, 0.644622, + 0.818947, 0.483773, 0.647656, + 0.821153, 0.487856, 0.650671, + 0.823150, 0.491898, 0.653657, + 0.824942, 0.495898, 0.656621, + 0.826547, 0.499867, 0.659541, + 0.827958, 0.503800, 0.662432, + 0.829202, 0.507681, 0.665273, + 0.830272, 0.511501, 0.668084, + 0.831190, 0.515276, 0.670847, + 0.831962, 0.519007, 0.673568, + 0.832595, 0.522672, 0.676250, + 0.833109, 0.526298, 0.678890, + 0.833513, 0.529868, 0.681492, + 0.833814, 0.533389, 0.684062, + 0.834021, 0.536885, 0.686602, + 0.834145, 0.540322, 0.689113, + 0.834196, 0.543731, 0.691583, + 0.834181, 0.547106, 0.694028, + 0.834110, 0.550453, 0.696461, + 0.833989, 0.553769, 0.698860, + 0.833825, 0.557074, 0.701248, + 0.833624, 0.560346, 0.703619, + 0.833394, 0.563609, 0.705976, + 0.833139, 0.566852, 0.708319, + 0.832866, 0.570077, 0.710651, + 0.832581, 0.573311, 0.712971, + 0.832288, 0.576535, 0.715295, + 0.831989, 0.579748, 0.717611, + 0.831689, 0.582952, 0.719918, + 0.831389, 0.586173, 0.722221, + 0.831094, 0.589380, 0.724534, + 0.830808, 0.592613, 0.726841, + 0.830534, 0.595831, 0.729152, + 0.830274, 0.599067, 0.731464, + 0.830031, 0.602304, 0.733784, + 0.829807, 0.605550, 0.736101, + 0.829605, 0.608823, 0.738432, + 0.829424, 0.612085, 0.740764, + 0.829268, 0.615369, 0.743111, + 0.829138, 0.618676, 0.745453, + 0.829036, 0.621976, 0.747814, + 0.828962, 0.625307, 0.750172, + 0.828918, 0.628653, 0.752543, + 0.828906, 0.632008, 0.754931, + 0.828926, 0.635378, 0.757317, + 0.828980, 0.638770, 0.759714, + 0.829067, 0.642178, 0.762124, + 0.829189, 0.645596, 0.764546, + 0.829346, 0.649044, 0.766973, + 0.829539, 0.652496, 0.769411, + 0.829768, 0.655978, 0.771864, + 0.830034, 0.659466, 0.774318, + 0.830337, 0.662981, 0.776794, + 0.830678, 0.666500, 0.779269, + 0.831057, 0.670054, 0.781761, + 0.831474, 0.673612, 0.784262, + 0.831926, 0.677196, 0.786770, + 0.832413, 0.680782, 0.789286, + 0.832939, 0.684396, 0.791810, + 0.833506, 0.688032, 0.794350, + 0.834109, 0.691677, 0.796891, + 0.834745, 0.695339, 0.799452, + 0.835417, 0.699014, 0.802010, + 0.836126, 0.702712, 0.804586, + 0.836872, 0.706423, 0.807167, + 0.837653, 0.710145, 0.809754, + 0.838462, 0.713881, 0.812350, + 0.839311, 0.717639, 0.814955, + 0.840192, 0.721397, 0.817566, + 0.841101, 0.725185, 0.820185, + 0.842045, 0.728973, 0.822816, + 0.843016, 0.732783, 0.825446, + 0.844017, 0.736597, 0.828087, + 0.845051, 0.740430, 0.830738, + 0.846109, 0.744271, 0.833390, + 0.847196, 0.748128, 0.836049, + 0.848312, 0.751992, 0.838712, + 0.849455, 0.755867, 0.841386, + 0.850615, 0.759748, 0.844060, + 0.851806, 0.763646, 0.846740, + 0.853017, 0.767550, 0.849432, + 0.854249, 0.771471, 0.852124, + 0.855508, 0.775390, 0.854819, + 0.856778, 0.779324, 0.857517, + 0.858072, 0.783265, 0.860226, + 0.859387, 0.787218, 0.862937, + 0.860717, 0.791171, 0.865647, + 0.862068, 0.795136, 0.868370, + 0.863431, 0.799112, 0.871086, + 0.864804, 0.803086, 0.873811, + 0.866199, 0.807076, 0.876538, + 0.867604, 0.811065, 0.879271, + 0.869025, 0.815063, 0.882009, + 0.870449, 0.819064, 0.884748, + 0.871896, 0.823078, 0.887487, + 0.873345, 0.827095, 0.890233, + 0.874806, 0.831118, 0.892981, + 0.876275, 0.835142, 0.895733, + 0.877755, 0.839173, 0.898483, + 0.879238, 0.843207, 0.901240, + 0.880732, 0.847246, 0.903997, + 0.882230, 0.851290, 0.906760, + 0.883737, 0.855346, 0.909522, + 0.885244, 0.859397, 0.912287, + 0.886759, 0.863458, 0.915053, + 0.888274, 0.867515, 0.917827, + 0.889793, 0.871582, 0.920592, + 0.891315, 0.875649, 0.923371, + 0.892840, 0.879718, 0.926144, + 0.894368, 0.883797, 0.928919, + 0.895893, 0.887870, 0.931699, + 0.897421, 0.891954, 0.934479, + 0.898946, 0.896037, 0.937266, + 0.900472, 0.900123, 0.940051, +}; + +const float ColorMap::m_imola[m_size] = +{ + 0.101441, 0.200110, 0.700194, + 0.103275, 0.203014, 0.698806, + 0.104955, 0.205896, 0.697423, + 0.106727, 0.208726, 0.696046, + 0.108299, 0.211567, 0.694659, + 0.109977, 0.214366, 0.693287, + 0.111521, 0.217161, 0.691913, + 0.113070, 0.219940, 0.690533, + 0.114496, 0.222699, 0.689172, + 0.116032, 0.225438, 0.687800, + 0.117443, 0.228185, 0.686435, + 0.118906, 0.230894, 0.685075, + 0.120279, 0.233585, 0.683714, + 0.121658, 0.236312, 0.682359, + 0.123038, 0.238984, 0.681006, + 0.124419, 0.241675, 0.679659, + 0.125813, 0.244322, 0.678320, + 0.127111, 0.246997, 0.676983, + 0.128474, 0.249641, 0.675640, + 0.129827, 0.252304, 0.674306, + 0.131137, 0.254955, 0.672979, + 0.132446, 0.257568, 0.671645, + 0.133757, 0.260201, 0.670328, + 0.135070, 0.262823, 0.669002, + 0.136327, 0.265434, 0.667684, + 0.137679, 0.268035, 0.666360, + 0.138935, 0.270668, 0.665046, + 0.140231, 0.273263, 0.663742, + 0.141543, 0.275872, 0.662432, + 0.142820, 0.278454, 0.661119, + 0.144107, 0.281028, 0.659816, + 0.145415, 0.283628, 0.658510, + 0.146648, 0.286201, 0.657214, + 0.147947, 0.288802, 0.655913, + 0.149229, 0.291388, 0.654606, + 0.150503, 0.293949, 0.653308, + 0.151764, 0.296539, 0.652018, + 0.153035, 0.299117, 0.650721, + 0.154318, 0.301673, 0.649430, + 0.155613, 0.304252, 0.648128, + 0.156880, 0.306831, 0.646841, + 0.158164, 0.309412, 0.645542, + 0.159416, 0.311952, 0.644249, + 0.160695, 0.314529, 0.642960, + 0.162002, 0.317106, 0.641664, + 0.163274, 0.319678, 0.640376, + 0.164543, 0.322244, 0.639079, + 0.165794, 0.324799, 0.637784, + 0.167115, 0.327367, 0.636491, + 0.168375, 0.329947, 0.635186, + 0.169688, 0.332517, 0.633890, + 0.170957, 0.335083, 0.632583, + 0.172248, 0.337633, 0.631277, + 0.173551, 0.340199, 0.629962, + 0.174877, 0.342765, 0.628648, + 0.176151, 0.345314, 0.627322, + 0.177520, 0.347876, 0.625992, + 0.178838, 0.350435, 0.624657, + 0.180160, 0.352981, 0.623315, + 0.181504, 0.355536, 0.621949, + 0.182872, 0.358073, 0.620594, + 0.184263, 0.360596, 0.619216, + 0.185685, 0.363136, 0.617815, + 0.187076, 0.365668, 0.616413, + 0.188513, 0.368188, 0.614982, + 0.189944, 0.370692, 0.613540, + 0.191409, 0.373200, 0.612083, + 0.192907, 0.375695, 0.610606, + 0.194447, 0.378180, 0.609108, + 0.195967, 0.380661, 0.607582, + 0.197527, 0.383122, 0.606021, + 0.199102, 0.385560, 0.604456, + 0.200717, 0.388001, 0.602850, + 0.202374, 0.390426, 0.601219, + 0.204080, 0.392837, 0.599568, + 0.205772, 0.395241, 0.597878, + 0.207501, 0.397623, 0.596167, + 0.209253, 0.399988, 0.594425, + 0.211048, 0.402341, 0.592662, + 0.212851, 0.404685, 0.590855, + 0.214697, 0.407021, 0.589024, + 0.216590, 0.409339, 0.587173, + 0.218472, 0.411640, 0.585301, + 0.220405, 0.413936, 0.583386, + 0.222326, 0.416219, 0.581455, + 0.224273, 0.418485, 0.579507, + 0.226292, 0.420749, 0.577521, + 0.228298, 0.423003, 0.575529, + 0.230292, 0.425262, 0.573509, + 0.232354, 0.427507, 0.571468, + 0.234418, 0.429738, 0.569412, + 0.236494, 0.431981, 0.567351, + 0.238559, 0.434195, 0.565258, + 0.240659, 0.436433, 0.563176, + 0.242782, 0.438655, 0.561063, + 0.244908, 0.440883, 0.558948, + 0.247068, 0.443126, 0.556836, + 0.249228, 0.445357, 0.554707, + 0.251414, 0.447595, 0.552578, + 0.253591, 0.449854, 0.550447, + 0.255782, 0.452118, 0.548322, + 0.257992, 0.454385, 0.546194, + 0.260238, 0.456657, 0.544064, + 0.262487, 0.458956, 0.541944, + 0.264746, 0.461264, 0.539834, + 0.267031, 0.463588, 0.537747, + 0.269365, 0.465931, 0.535653, + 0.271670, 0.468302, 0.533584, + 0.274045, 0.470701, 0.531541, + 0.276437, 0.473109, 0.529517, + 0.278846, 0.475569, 0.527507, + 0.281273, 0.478037, 0.525529, + 0.283755, 0.480545, 0.523580, + 0.286254, 0.483087, 0.521652, + 0.288817, 0.485665, 0.519766, + 0.291406, 0.488292, 0.517923, + 0.294012, 0.490955, 0.516096, + 0.296691, 0.493641, 0.514334, + 0.299399, 0.496376, 0.512590, + 0.302129, 0.499165, 0.510895, + 0.304936, 0.502001, 0.509249, + 0.307762, 0.504874, 0.507643, + 0.310668, 0.507797, 0.506069, + 0.313590, 0.510755, 0.504562, + 0.316562, 0.513775, 0.503071, + 0.319579, 0.516828, 0.501649, + 0.322646, 0.519921, 0.500247, + 0.325731, 0.523075, 0.498902, + 0.328896, 0.526263, 0.497597, + 0.332081, 0.529491, 0.496307, + 0.335316, 0.532757, 0.495080, + 0.338565, 0.536058, 0.493873, + 0.341872, 0.539398, 0.492693, + 0.345206, 0.542783, 0.491567, + 0.348575, 0.546195, 0.490446, + 0.351966, 0.549630, 0.489345, + 0.355415, 0.553094, 0.488287, + 0.358852, 0.556596, 0.487239, + 0.362345, 0.560123, 0.486202, + 0.365854, 0.563673, 0.485185, + 0.369381, 0.567240, 0.484185, + 0.372929, 0.570823, 0.483199, + 0.376515, 0.574431, 0.482229, + 0.380098, 0.578061, 0.481253, + 0.383710, 0.581709, 0.480296, + 0.387326, 0.585380, 0.479342, + 0.390980, 0.589046, 0.478387, + 0.394629, 0.592751, 0.477439, + 0.398306, 0.596451, 0.476496, + 0.401978, 0.600169, 0.475558, + 0.405692, 0.603906, 0.474615, + 0.409398, 0.607651, 0.473662, + 0.413126, 0.611403, 0.472723, + 0.416860, 0.615163, 0.471790, + 0.420597, 0.618953, 0.470843, + 0.424359, 0.622735, 0.469902, + 0.428133, 0.626534, 0.468954, + 0.431922, 0.630349, 0.467997, + 0.435709, 0.634172, 0.467055, + 0.439505, 0.637999, 0.466094, + 0.443323, 0.641840, 0.465140, + 0.447143, 0.645690, 0.464197, + 0.450983, 0.649560, 0.463220, + 0.454835, 0.653426, 0.462265, + 0.458687, 0.657318, 0.461305, + 0.462548, 0.661207, 0.460331, + 0.466433, 0.665110, 0.459373, + 0.470328, 0.669029, 0.458397, + 0.474226, 0.672957, 0.457422, + 0.478136, 0.676893, 0.456446, + 0.482064, 0.680831, 0.455471, + 0.485991, 0.684792, 0.454495, + 0.489937, 0.688766, 0.453502, + 0.493897, 0.692746, 0.452527, + 0.497874, 0.696730, 0.451532, + 0.501847, 0.700731, 0.450538, + 0.505825, 0.704741, 0.449545, + 0.509834, 0.708768, 0.448549, + 0.513854, 0.712792, 0.447538, + 0.517878, 0.716845, 0.446543, + 0.521903, 0.720893, 0.445532, + 0.525961, 0.724966, 0.444538, + 0.530021, 0.729039, 0.443523, + 0.534088, 0.733130, 0.442513, + 0.538185, 0.737229, 0.441493, + 0.542279, 0.741336, 0.440469, + 0.546397, 0.745461, 0.439450, + 0.550519, 0.749592, 0.438427, + 0.554662, 0.753743, 0.437409, + 0.558814, 0.757902, 0.436376, + 0.563001, 0.762067, 0.435350, + 0.567196, 0.766250, 0.434306, + 0.571406, 0.770443, 0.433272, + 0.575652, 0.774644, 0.432249, + 0.579917, 0.778862, 0.431207, + 0.584205, 0.783089, 0.430163, + 0.588525, 0.787331, 0.429123, + 0.592898, 0.791580, 0.428085, + 0.597297, 0.795841, 0.427048, + 0.601739, 0.800118, 0.425999, + 0.606235, 0.804401, 0.424971, + 0.610797, 0.808695, 0.423927, + 0.615410, 0.812993, 0.422894, + 0.620108, 0.817305, 0.421867, + 0.624872, 0.821627, 0.420848, + 0.629725, 0.825948, 0.419844, + 0.634681, 0.830279, 0.418834, + 0.639735, 0.834610, 0.417842, + 0.644895, 0.838937, 0.416866, + 0.650187, 0.843264, 0.415892, + 0.655603, 0.847585, 0.414941, + 0.661151, 0.851901, 0.414009, + 0.666842, 0.856200, 0.413104, + 0.672692, 0.860483, 0.412213, + 0.678680, 0.864742, 0.411341, + 0.684831, 0.868982, 0.410515, + 0.691137, 0.873182, 0.409702, + 0.697607, 0.877350, 0.408922, + 0.704236, 0.881483, 0.408178, + 0.711022, 0.885567, 0.407469, + 0.717955, 0.889601, 0.406798, + 0.725038, 0.893583, 0.406169, + 0.732260, 0.897513, 0.405572, + 0.739616, 0.901376, 0.405005, + 0.747090, 0.905184, 0.404485, + 0.754686, 0.908919, 0.404012, + 0.762378, 0.912595, 0.403574, + 0.770173, 0.916201, 0.403168, + 0.778055, 0.919746, 0.402796, + 0.786012, 0.923226, 0.402459, + 0.794034, 0.926637, 0.402157, + 0.802106, 0.929992, 0.401890, + 0.810230, 0.933282, 0.401656, + 0.818395, 0.936527, 0.401452, + 0.826599, 0.939711, 0.401272, + 0.834823, 0.942847, 0.401115, + 0.843067, 0.945933, 0.400978, + 0.851325, 0.948981, 0.400859, + 0.859601, 0.951989, 0.400755, + 0.867883, 0.954967, 0.400665, + 0.876163, 0.957911, 0.400588, + 0.884451, 0.960825, 0.400522, + 0.892736, 0.963712, 0.400466, + 0.901018, 0.966580, 0.400418, + 0.909297, 0.969428, 0.400377, + 0.917577, 0.972263, 0.400342, + 0.925845, 0.975074, 0.400311, + 0.934106, 0.977879, 0.400283, + 0.942371, 0.980672, 0.400258, + 0.950623, 0.983452, 0.400235, + 0.958870, 0.986227, 0.400212, + 0.967110, 0.988992, 0.400190, + 0.975342, 0.991749, 0.400168, + 0.983572, 0.994500, 0.400145, + 0.991797, 0.997245, 0.400120, + 1.000000, 0.999989, 0.400094, +}; + +const float ColorMap::m_tokyo[m_size] = +{ + 0.103874, 0.056805, 0.202430, + 0.109754, 0.059104, 0.205635, + 0.115663, 0.061046, 0.208843, + 0.121598, 0.063055, 0.212092, + 0.127575, 0.064935, 0.215312, + 0.133515, 0.066895, 0.218581, + 0.139386, 0.068939, 0.221840, + 0.145346, 0.070894, 0.225122, + 0.151193, 0.072938, 0.228453, + 0.157077, 0.074970, 0.231771, + 0.162979, 0.077038, 0.235110, + 0.168863, 0.079188, 0.238435, + 0.174746, 0.081435, 0.241823, + 0.180609, 0.083639, 0.245194, + 0.186520, 0.085843, 0.248633, + 0.192425, 0.088221, 0.252056, + 0.198334, 0.090586, 0.255503, + 0.204293, 0.092949, 0.258980, + 0.210211, 0.095479, 0.262461, + 0.216186, 0.098018, 0.265979, + 0.222124, 0.100564, 0.269515, + 0.228121, 0.103253, 0.273058, + 0.234096, 0.105965, 0.276636, + 0.240087, 0.108708, 0.280212, + 0.246101, 0.111594, 0.283828, + 0.252139, 0.114453, 0.287452, + 0.258153, 0.117464, 0.291117, + 0.264210, 0.120519, 0.294769, + 0.270259, 0.123649, 0.298454, + 0.276307, 0.126865, 0.302145, + 0.282356, 0.130211, 0.305884, + 0.288387, 0.133541, 0.309605, + 0.294424, 0.136973, 0.313331, + 0.300463, 0.140494, 0.317072, + 0.306506, 0.144083, 0.320832, + 0.312496, 0.147750, 0.324572, + 0.318504, 0.151468, 0.328340, + 0.324470, 0.155292, 0.332107, + 0.330424, 0.159176, 0.335860, + 0.336337, 0.163148, 0.339626, + 0.342232, 0.167175, 0.343369, + 0.348076, 0.171244, 0.347114, + 0.353869, 0.175399, 0.350843, + 0.359631, 0.179615, 0.354554, + 0.365331, 0.183889, 0.358244, + 0.370972, 0.188248, 0.361925, + 0.376573, 0.192607, 0.365573, + 0.382077, 0.197055, 0.369202, + 0.387525, 0.201501, 0.372794, + 0.392902, 0.206057, 0.376376, + 0.398204, 0.210595, 0.379900, + 0.403416, 0.215176, 0.383404, + 0.408536, 0.219817, 0.386848, + 0.413574, 0.224434, 0.390266, + 0.418507, 0.229127, 0.393641, + 0.423351, 0.233801, 0.396964, + 0.428105, 0.238504, 0.400253, + 0.432750, 0.243215, 0.403484, + 0.437290, 0.247962, 0.406658, + 0.441721, 0.252674, 0.409786, + 0.446034, 0.257394, 0.412860, + 0.450256, 0.262114, 0.415866, + 0.454365, 0.266821, 0.418823, + 0.458352, 0.271520, 0.421720, + 0.462234, 0.276236, 0.424573, + 0.466002, 0.280883, 0.427366, + 0.469677, 0.285545, 0.430087, + 0.473210, 0.290189, 0.432760, + 0.476659, 0.294809, 0.435375, + 0.479995, 0.299421, 0.437928, + 0.483211, 0.303979, 0.440413, + 0.486332, 0.308535, 0.442859, + 0.489342, 0.313046, 0.445236, + 0.492259, 0.317537, 0.447556, + 0.495074, 0.321996, 0.449837, + 0.497794, 0.326417, 0.452061, + 0.500399, 0.330819, 0.454223, + 0.502919, 0.335210, 0.456331, + 0.505351, 0.339545, 0.458395, + 0.507706, 0.343834, 0.460403, + 0.509958, 0.348119, 0.462373, + 0.512132, 0.352358, 0.464307, + 0.514235, 0.356582, 0.466168, + 0.516239, 0.360748, 0.468000, + 0.518191, 0.364909, 0.469800, + 0.520050, 0.369042, 0.471546, + 0.521848, 0.373130, 0.473241, + 0.523591, 0.377205, 0.474929, + 0.525257, 0.381250, 0.476556, + 0.526870, 0.385250, 0.478154, + 0.528414, 0.389248, 0.479726, + 0.529905, 0.393206, 0.481251, + 0.531341, 0.397143, 0.482757, + 0.532731, 0.401075, 0.484226, + 0.534059, 0.404954, 0.485673, + 0.535350, 0.408831, 0.487099, + 0.536606, 0.412692, 0.488492, + 0.537810, 0.416517, 0.489853, + 0.538970, 0.420326, 0.491215, + 0.540090, 0.424120, 0.492521, + 0.541178, 0.427906, 0.493829, + 0.542238, 0.431673, 0.495114, + 0.543262, 0.435417, 0.496367, + 0.544252, 0.439136, 0.497628, + 0.545217, 0.442864, 0.498851, + 0.546158, 0.446565, 0.500055, + 0.547062, 0.450259, 0.501264, + 0.547950, 0.453939, 0.502441, + 0.548817, 0.457607, 0.503609, + 0.549655, 0.461272, 0.504773, + 0.550476, 0.464923, 0.505906, + 0.551279, 0.468564, 0.507047, + 0.552068, 0.472205, 0.508179, + 0.552830, 0.475831, 0.509286, + 0.553581, 0.479451, 0.510385, + 0.554326, 0.483058, 0.511479, + 0.555048, 0.486669, 0.512567, + 0.555755, 0.490274, 0.513652, + 0.556462, 0.493871, 0.514722, + 0.557162, 0.497470, 0.515776, + 0.557835, 0.501057, 0.516843, + 0.558500, 0.504647, 0.517897, + 0.559168, 0.508232, 0.518945, + 0.559829, 0.511802, 0.519974, + 0.560474, 0.515380, 0.521015, + 0.561112, 0.518967, 0.522039, + 0.561754, 0.522535, 0.523077, + 0.562388, 0.526115, 0.524096, + 0.563011, 0.529688, 0.525114, + 0.563633, 0.533255, 0.526133, + 0.564247, 0.536837, 0.527144, + 0.564853, 0.540403, 0.528148, + 0.565463, 0.543976, 0.529160, + 0.566077, 0.547547, 0.530157, + 0.566689, 0.551124, 0.531156, + 0.567294, 0.554700, 0.532156, + 0.567895, 0.558269, 0.533147, + 0.568496, 0.561859, 0.534136, + 0.569099, 0.565427, 0.535129, + 0.569703, 0.569012, 0.536120, + 0.570308, 0.572605, 0.537115, + 0.570916, 0.576196, 0.538101, + 0.571526, 0.579783, 0.539079, + 0.572140, 0.583367, 0.540059, + 0.572757, 0.586964, 0.541042, + 0.573371, 0.590563, 0.542024, + 0.573986, 0.594170, 0.543012, + 0.574608, 0.597777, 0.543990, + 0.575244, 0.601388, 0.544972, + 0.575888, 0.605007, 0.545958, + 0.576531, 0.608637, 0.546936, + 0.577173, 0.612254, 0.547919, + 0.577825, 0.615890, 0.548907, + 0.578494, 0.619537, 0.549888, + 0.579177, 0.623182, 0.550875, + 0.579866, 0.626832, 0.551868, + 0.580561, 0.630500, 0.552855, + 0.581270, 0.634172, 0.553852, + 0.581995, 0.637846, 0.554854, + 0.582737, 0.641532, 0.555851, + 0.583497, 0.645232, 0.556875, + 0.584276, 0.648949, 0.557885, + 0.585079, 0.652666, 0.558907, + 0.585899, 0.656410, 0.559947, + 0.586736, 0.660155, 0.560982, + 0.587602, 0.663922, 0.562043, + 0.588497, 0.667703, 0.563104, + 0.589424, 0.671494, 0.564178, + 0.590386, 0.675311, 0.565256, + 0.591385, 0.679143, 0.566370, + 0.592425, 0.683002, 0.567492, + 0.593494, 0.686879, 0.568627, + 0.594610, 0.690776, 0.569787, + 0.595776, 0.694703, 0.570973, + 0.596998, 0.698658, 0.572187, + 0.598263, 0.702644, 0.573423, + 0.599602, 0.706660, 0.574680, + 0.600992, 0.710704, 0.575991, + 0.602456, 0.714779, 0.577314, + 0.603999, 0.718897, 0.578684, + 0.605602, 0.723049, 0.580099, + 0.607310, 0.727246, 0.581547, + 0.609095, 0.731483, 0.583047, + 0.610971, 0.735764, 0.584603, + 0.612942, 0.740100, 0.586210, + 0.615027, 0.744473, 0.587867, + 0.617229, 0.748900, 0.589592, + 0.619550, 0.753381, 0.591390, + 0.621980, 0.757921, 0.593253, + 0.624560, 0.762508, 0.595185, + 0.627269, 0.767157, 0.597203, + 0.630128, 0.771868, 0.599299, + 0.633135, 0.776637, 0.601476, + 0.636305, 0.781462, 0.603756, + 0.639633, 0.786350, 0.606115, + 0.643130, 0.791291, 0.608593, + 0.646810, 0.796294, 0.611159, + 0.650666, 0.801356, 0.613824, + 0.654704, 0.806477, 0.616616, + 0.658936, 0.811644, 0.619512, + 0.663368, 0.816862, 0.622512, + 0.667984, 0.822127, 0.625636, + 0.672796, 0.827426, 0.628877, + 0.677803, 0.832762, 0.632232, + 0.683000, 0.838129, 0.635702, + 0.688394, 0.843511, 0.639291, + 0.693965, 0.848913, 0.642991, + 0.699729, 0.854314, 0.646806, + 0.705669, 0.859715, 0.650725, + 0.711776, 0.865095, 0.654744, + 0.718039, 0.870453, 0.658868, + 0.724452, 0.875781, 0.663094, + 0.731000, 0.881058, 0.667395, + 0.737676, 0.886282, 0.671776, + 0.744467, 0.891433, 0.676236, + 0.751359, 0.896511, 0.680752, + 0.758327, 0.901496, 0.685338, + 0.765368, 0.906386, 0.689964, + 0.772456, 0.911166, 0.694625, + 0.779589, 0.915826, 0.699323, + 0.786752, 0.920367, 0.704045, + 0.793919, 0.924774, 0.708782, + 0.801076, 0.929045, 0.713515, + 0.808223, 0.933171, 0.718248, + 0.815338, 0.937156, 0.722969, + 0.822415, 0.940982, 0.727678, + 0.829438, 0.944660, 0.732366, + 0.836396, 0.948178, 0.737015, + 0.843285, 0.951544, 0.741630, + 0.850102, 0.954757, 0.746210, + 0.856831, 0.957816, 0.750750, + 0.863479, 0.960723, 0.755237, + 0.870023, 0.963479, 0.759670, + 0.876480, 0.966091, 0.764060, + 0.882838, 0.968566, 0.768392, + 0.889102, 0.970900, 0.772676, + 0.895264, 0.973107, 0.776909, + 0.901325, 0.975180, 0.781079, + 0.907294, 0.977138, 0.785201, + 0.913165, 0.978977, 0.789269, + 0.918939, 0.980708, 0.793287, + 0.924629, 0.982335, 0.797248, + 0.930235, 0.983860, 0.801169, + 0.935755, 0.985295, 0.805042, + 0.941192, 0.986643, 0.808876, + 0.946558, 0.987907, 0.812660, + 0.951853, 0.989101, 0.816415, + 0.957082, 0.990222, 0.820124, + 0.962248, 0.991280, 0.823806, + 0.967363, 0.992281, 0.827457, + 0.972422, 0.993229, 0.831083, + 0.977430, 0.994125, 0.834679, + 0.982400, 0.994978, 0.838253, + 0.987328, 0.995795, 0.841810, + 0.992221, 0.996578, 0.845345, + 0.997080, 0.997331, 0.848870, +}; + +const float ColorMap::m_lapaz[m_size] = +{ + 0.103516, 0.047787, 0.393530, + 0.104891, 0.053521, 0.396743, + 0.106384, 0.059148, 0.399962, + 0.107720, 0.064483, 0.403185, + 0.109104, 0.069760, 0.406401, + 0.110449, 0.074827, 0.409614, + 0.111749, 0.079829, 0.412831, + 0.113050, 0.084796, 0.416030, + 0.114243, 0.089643, 0.419241, + 0.115510, 0.094446, 0.422431, + 0.116730, 0.099126, 0.425637, + 0.117933, 0.103813, 0.428830, + 0.119106, 0.108384, 0.432027, + 0.120235, 0.113025, 0.435205, + 0.121361, 0.117507, 0.438371, + 0.122480, 0.121983, 0.441541, + 0.123592, 0.126483, 0.444704, + 0.124696, 0.130936, 0.447839, + 0.125807, 0.135324, 0.450989, + 0.126828, 0.139672, 0.454121, + 0.127907, 0.144071, 0.457236, + 0.128916, 0.148382, 0.460341, + 0.129993, 0.152699, 0.463441, + 0.130992, 0.157010, 0.466534, + 0.131988, 0.161319, 0.469615, + 0.132983, 0.165534, 0.472664, + 0.133979, 0.169826, 0.475718, + 0.134969, 0.174047, 0.478744, + 0.135893, 0.178292, 0.481764, + 0.136892, 0.182461, 0.484757, + 0.137889, 0.186673, 0.487756, + 0.138819, 0.190854, 0.490726, + 0.139754, 0.195043, 0.493668, + 0.140766, 0.199185, 0.496597, + 0.141712, 0.203360, 0.499513, + 0.142665, 0.207508, 0.502416, + 0.143626, 0.211653, 0.505290, + 0.144593, 0.215776, 0.508162, + 0.145575, 0.219893, 0.510990, + 0.146497, 0.223982, 0.513817, + 0.147494, 0.228107, 0.516608, + 0.148441, 0.232196, 0.519386, + 0.149461, 0.236283, 0.522132, + 0.150439, 0.240331, 0.524870, + 0.151423, 0.244401, 0.527578, + 0.152426, 0.248494, 0.530265, + 0.153444, 0.252535, 0.532927, + 0.154482, 0.256572, 0.535558, + 0.155540, 0.260614, 0.538183, + 0.156604, 0.264639, 0.540764, + 0.157646, 0.268677, 0.543330, + 0.158755, 0.272676, 0.545871, + 0.159813, 0.276698, 0.548383, + 0.160964, 0.280675, 0.550863, + 0.162111, 0.284675, 0.553315, + 0.163261, 0.288671, 0.555744, + 0.164432, 0.292642, 0.558150, + 0.165586, 0.296623, 0.560533, + 0.166843, 0.300573, 0.562887, + 0.168054, 0.304534, 0.565194, + 0.169354, 0.308487, 0.567495, + 0.170614, 0.312410, 0.569751, + 0.171920, 0.316363, 0.571989, + 0.173261, 0.320291, 0.574188, + 0.174648, 0.324189, 0.576375, + 0.176006, 0.328102, 0.578508, + 0.177479, 0.332008, 0.580625, + 0.178923, 0.335895, 0.582704, + 0.180394, 0.339788, 0.584762, + 0.181911, 0.343652, 0.586779, + 0.183476, 0.347530, 0.588765, + 0.185095, 0.351381, 0.590726, + 0.186704, 0.355244, 0.592662, + 0.188390, 0.359065, 0.594548, + 0.190072, 0.362901, 0.596411, + 0.191813, 0.366733, 0.598235, + 0.193613, 0.370536, 0.600036, + 0.195424, 0.374356, 0.601796, + 0.197303, 0.378144, 0.603531, + 0.199191, 0.381929, 0.605220, + 0.201145, 0.385703, 0.606888, + 0.203166, 0.389479, 0.608518, + 0.205211, 0.393235, 0.610101, + 0.207319, 0.396980, 0.611662, + 0.209453, 0.400739, 0.613179, + 0.211665, 0.404450, 0.614666, + 0.213901, 0.408173, 0.616123, + 0.216213, 0.411881, 0.617536, + 0.218546, 0.415577, 0.618923, + 0.220963, 0.419268, 0.620264, + 0.223407, 0.422932, 0.621560, + 0.225926, 0.426601, 0.622832, + 0.228495, 0.430255, 0.624066, + 0.231110, 0.433884, 0.625253, + 0.233772, 0.437528, 0.626406, + 0.236537, 0.441129, 0.627522, + 0.239324, 0.444741, 0.628602, + 0.242179, 0.448322, 0.629632, + 0.245082, 0.451902, 0.630636, + 0.248092, 0.455457, 0.631588, + 0.251124, 0.459003, 0.632503, + 0.254223, 0.462523, 0.633378, + 0.257378, 0.466038, 0.634215, + 0.260601, 0.469550, 0.635000, + 0.263901, 0.473016, 0.635749, + 0.267221, 0.476488, 0.636460, + 0.270662, 0.479939, 0.637121, + 0.274124, 0.483358, 0.637738, + 0.277664, 0.486772, 0.638314, + 0.281249, 0.490161, 0.638845, + 0.284909, 0.493528, 0.639333, + 0.288645, 0.496877, 0.639778, + 0.292426, 0.500203, 0.640175, + 0.296276, 0.503508, 0.640524, + 0.300180, 0.506793, 0.640826, + 0.304147, 0.510052, 0.641084, + 0.308175, 0.513289, 0.641296, + 0.312252, 0.516494, 0.641462, + 0.316418, 0.519677, 0.641582, + 0.320626, 0.522837, 0.641654, + 0.324864, 0.525966, 0.641679, + 0.329198, 0.529070, 0.641656, + 0.333561, 0.532136, 0.641585, + 0.337970, 0.535170, 0.641466, + 0.342455, 0.538188, 0.641300, + 0.346979, 0.541154, 0.641087, + 0.351541, 0.544103, 0.640829, + 0.356170, 0.547014, 0.640524, + 0.360819, 0.549891, 0.640171, + 0.365541, 0.552731, 0.639769, + 0.370290, 0.555531, 0.639318, + 0.375088, 0.558300, 0.638823, + 0.379928, 0.561035, 0.638283, + 0.384797, 0.563739, 0.637697, + 0.389709, 0.566390, 0.637069, + 0.394658, 0.569000, 0.636397, + 0.399630, 0.571580, 0.635673, + 0.404644, 0.574114, 0.634914, + 0.409695, 0.576622, 0.634116, + 0.414760, 0.579073, 0.633268, + 0.419859, 0.581482, 0.632384, + 0.424982, 0.583855, 0.631463, + 0.430122, 0.586191, 0.630505, + 0.435295, 0.588472, 0.629501, + 0.440469, 0.590724, 0.628476, + 0.445670, 0.592938, 0.627405, + 0.450901, 0.595097, 0.626305, + 0.456135, 0.597226, 0.625177, + 0.461391, 0.599309, 0.624023, + 0.466657, 0.601347, 0.622832, + 0.471940, 0.603355, 0.621614, + 0.477222, 0.605313, 0.620388, + 0.482525, 0.607248, 0.619130, + 0.487841, 0.609136, 0.617842, + 0.493147, 0.610986, 0.616551, + 0.498489, 0.612795, 0.615232, + 0.503819, 0.614576, 0.613904, + 0.509165, 0.616333, 0.612569, + 0.514519, 0.618048, 0.611232, + 0.519869, 0.619742, 0.609876, + 0.525243, 0.621396, 0.608531, + 0.530620, 0.623035, 0.607177, + 0.536002, 0.624643, 0.605815, + 0.541393, 0.626229, 0.604481, + 0.546807, 0.627800, 0.603143, + 0.552224, 0.629346, 0.601817, + 0.557650, 0.630889, 0.600512, + 0.563095, 0.632409, 0.599231, + 0.568544, 0.633927, 0.597963, + 0.574017, 0.635428, 0.596735, + 0.579518, 0.636939, 0.595529, + 0.585029, 0.638440, 0.594365, + 0.590556, 0.639951, 0.593245, + 0.596118, 0.641459, 0.592171, + 0.601704, 0.642989, 0.591137, + 0.607328, 0.644526, 0.590163, + 0.612966, 0.646088, 0.589253, + 0.618659, 0.647671, 0.588412, + 0.624377, 0.649288, 0.587646, + 0.630138, 0.650926, 0.586960, + 0.635943, 0.652601, 0.586361, + 0.641792, 0.654323, 0.585856, + 0.647693, 0.656096, 0.585447, + 0.653648, 0.657914, 0.585142, + 0.659659, 0.659784, 0.584952, + 0.665727, 0.661724, 0.584884, + 0.671854, 0.663726, 0.584946, + 0.678048, 0.665796, 0.585146, + 0.684298, 0.667952, 0.585491, + 0.690623, 0.670187, 0.585987, + 0.697019, 0.672507, 0.586641, + 0.703483, 0.674915, 0.587468, + 0.710016, 0.677433, 0.588473, + 0.716622, 0.680035, 0.589666, + 0.723287, 0.682758, 0.591058, + 0.730033, 0.685590, 0.592654, + 0.736837, 0.688533, 0.594444, + 0.743708, 0.691588, 0.596458, + 0.750639, 0.694763, 0.598689, + 0.757620, 0.698063, 0.601149, + 0.764653, 0.701485, 0.603849, + 0.771730, 0.705033, 0.606775, + 0.778837, 0.708706, 0.609936, + 0.785977, 0.712489, 0.613340, + 0.793132, 0.716409, 0.616996, + 0.800292, 0.720435, 0.620887, + 0.807448, 0.724584, 0.625012, + 0.814587, 0.728840, 0.629376, + 0.821705, 0.733207, 0.633983, + 0.828779, 0.737670, 0.638805, + 0.835797, 0.742236, 0.643850, + 0.842753, 0.746885, 0.649121, + 0.849627, 0.751621, 0.654582, + 0.856405, 0.756422, 0.660250, + 0.863083, 0.761293, 0.666100, + 0.869635, 0.766222, 0.672129, + 0.876063, 0.771202, 0.678318, + 0.882346, 0.776217, 0.684656, + 0.888482, 0.781266, 0.691134, + 0.894454, 0.786340, 0.697742, + 0.900253, 0.791422, 0.704464, + 0.905879, 0.796513, 0.711290, + 0.911317, 0.801607, 0.718196, + 0.916568, 0.806696, 0.725189, + 0.921627, 0.811765, 0.732241, + 0.926488, 0.816815, 0.739352, + 0.931155, 0.821841, 0.746497, + 0.935622, 0.826833, 0.753683, + 0.939894, 0.831794, 0.760897, + 0.943965, 0.836710, 0.768122, + 0.947844, 0.841589, 0.775364, + 0.951530, 0.846418, 0.782609, + 0.955031, 0.851205, 0.789852, + 0.958348, 0.855950, 0.797083, + 0.961481, 0.860641, 0.804310, + 0.964444, 0.865281, 0.811517, + 0.967245, 0.869874, 0.818701, + 0.969877, 0.874421, 0.825872, + 0.972359, 0.878918, 0.833018, + 0.974685, 0.883371, 0.840145, + 0.976874, 0.887774, 0.847236, + 0.978925, 0.892139, 0.854310, + 0.980850, 0.896458, 0.861358, + 0.982652, 0.900735, 0.868388, + 0.984338, 0.904979, 0.875383, + 0.985912, 0.909180, 0.882357, + 0.987387, 0.913355, 0.889315, + 0.988763, 0.917498, 0.896251, + 0.990052, 0.921606, 0.903168, + 0.991256, 0.925692, 0.910067, + 0.992385, 0.929753, 0.916951, + 0.993443, 0.933791, 0.923821, + 0.994431, 0.937817, 0.930680, + 0.995360, 0.941823, 0.937528, + 0.996235, 0.945814, 0.944370, + 0.997061, 0.949794, 0.951206, +}; + +const float ColorMap::m_buda[m_size] = +{ + 0.700151, 0.002745, 0.700612, + 0.700191, 0.010833, 0.697186, + 0.700226, 0.019196, 0.693784, + 0.700255, 0.027497, 0.690410, + 0.700279, 0.036129, 0.687067, + 0.700299, 0.044535, 0.683750, + 0.700315, 0.052201, 0.680467, + 0.700328, 0.059479, 0.677234, + 0.700339, 0.066138, 0.674024, + 0.700347, 0.072500, 0.670865, + 0.700355, 0.078557, 0.667747, + 0.700362, 0.084489, 0.664665, + 0.700369, 0.090118, 0.661647, + 0.700378, 0.095602, 0.658662, + 0.700389, 0.100919, 0.655740, + 0.700403, 0.106180, 0.652854, + 0.700422, 0.111272, 0.650035, + 0.700447, 0.116281, 0.647260, + 0.700479, 0.121141, 0.644532, + 0.700521, 0.126029, 0.641864, + 0.700575, 0.130794, 0.639246, + 0.700642, 0.135455, 0.636684, + 0.700726, 0.140079, 0.634169, + 0.700829, 0.144685, 0.631701, + 0.700953, 0.149193, 0.629284, + 0.701102, 0.153641, 0.626923, + 0.701279, 0.158084, 0.624615, + 0.701486, 0.162466, 0.622349, + 0.701729, 0.166801, 0.620147, + 0.702012, 0.171076, 0.617979, + 0.702337, 0.175336, 0.615867, + 0.702707, 0.179555, 0.613800, + 0.703122, 0.183741, 0.611790, + 0.703582, 0.187936, 0.609823, + 0.704093, 0.192033, 0.607911, + 0.704658, 0.196154, 0.606029, + 0.705275, 0.200200, 0.604213, + 0.705946, 0.204298, 0.602424, + 0.706671, 0.208310, 0.600685, + 0.707439, 0.212332, 0.598992, + 0.708265, 0.216333, 0.597337, + 0.709140, 0.220302, 0.595714, + 0.710053, 0.224219, 0.594134, + 0.711015, 0.228186, 0.592595, + 0.712011, 0.232099, 0.591073, + 0.713044, 0.235997, 0.589585, + 0.714113, 0.239864, 0.588131, + 0.715214, 0.243717, 0.586706, + 0.716339, 0.247586, 0.585309, + 0.717485, 0.251421, 0.583920, + 0.718642, 0.255233, 0.582557, + 0.719825, 0.259028, 0.581216, + 0.721012, 0.262798, 0.579897, + 0.722212, 0.266557, 0.578580, + 0.723423, 0.270315, 0.577284, + 0.724641, 0.274034, 0.576009, + 0.725860, 0.277747, 0.574723, + 0.727075, 0.281433, 0.573468, + 0.728294, 0.285107, 0.572216, + 0.729516, 0.288786, 0.570967, + 0.730731, 0.292428, 0.569729, + 0.731948, 0.296063, 0.568502, + 0.733159, 0.299689, 0.567287, + 0.734368, 0.303280, 0.566067, + 0.735568, 0.306883, 0.564853, + 0.736769, 0.310471, 0.563661, + 0.737963, 0.314024, 0.562464, + 0.739164, 0.317574, 0.561261, + 0.740347, 0.321115, 0.560077, + 0.741527, 0.324632, 0.558885, + 0.742714, 0.328153, 0.557711, + 0.743886, 0.331654, 0.556532, + 0.745056, 0.335166, 0.555357, + 0.746225, 0.338633, 0.554196, + 0.747393, 0.342111, 0.553026, + 0.748552, 0.345565, 0.551874, + 0.749704, 0.349024, 0.550714, + 0.750868, 0.352465, 0.549561, + 0.752015, 0.355908, 0.548416, + 0.753158, 0.359324, 0.547260, + 0.754311, 0.362743, 0.546124, + 0.755451, 0.366162, 0.544977, + 0.756589, 0.369556, 0.543837, + 0.757726, 0.372949, 0.542705, + 0.758860, 0.376350, 0.541561, + 0.759990, 0.379722, 0.540437, + 0.761122, 0.383103, 0.539305, + 0.762246, 0.386459, 0.538189, + 0.763371, 0.389823, 0.537065, + 0.764497, 0.393183, 0.535933, + 0.765621, 0.396533, 0.534816, + 0.766735, 0.399878, 0.533691, + 0.767850, 0.403228, 0.532586, + 0.768965, 0.406563, 0.531468, + 0.770080, 0.409898, 0.530357, + 0.771197, 0.413225, 0.529252, + 0.772302, 0.416545, 0.528136, + 0.773408, 0.419864, 0.527036, + 0.774514, 0.423171, 0.525928, + 0.775620, 0.426487, 0.524822, + 0.776727, 0.429800, 0.523723, + 0.777826, 0.433105, 0.522621, + 0.778921, 0.436413, 0.521521, + 0.780016, 0.439713, 0.520427, + 0.781110, 0.443016, 0.519342, + 0.782202, 0.446308, 0.518256, + 0.783285, 0.449611, 0.517171, + 0.784373, 0.452911, 0.516077, + 0.785450, 0.456202, 0.515007, + 0.786526, 0.459505, 0.513939, + 0.787590, 0.462792, 0.512865, + 0.788657, 0.466096, 0.511800, + 0.789713, 0.469411, 0.510744, + 0.790763, 0.472703, 0.509696, + 0.791807, 0.476015, 0.508661, + 0.792845, 0.479325, 0.507622, + 0.793877, 0.482635, 0.506589, + 0.794892, 0.485949, 0.505565, + 0.795900, 0.489268, 0.504572, + 0.796901, 0.492594, 0.503560, + 0.797894, 0.495924, 0.502571, + 0.798879, 0.499261, 0.501599, + 0.799853, 0.502601, 0.500622, + 0.800811, 0.505942, 0.499654, + 0.801763, 0.509301, 0.498715, + 0.802706, 0.512652, 0.497778, + 0.803641, 0.516005, 0.496832, + 0.804568, 0.519378, 0.495907, + 0.805481, 0.522745, 0.495000, + 0.806395, 0.526120, 0.494092, + 0.807296, 0.529496, 0.493183, + 0.808190, 0.532873, 0.492294, + 0.809081, 0.536254, 0.491419, + 0.809960, 0.539633, 0.490532, + 0.810839, 0.543029, 0.489643, + 0.811716, 0.546423, 0.488777, + 0.812583, 0.549811, 0.487916, + 0.813449, 0.553199, 0.487046, + 0.814314, 0.556601, 0.486178, + 0.815178, 0.560003, 0.485315, + 0.816042, 0.563405, 0.484456, + 0.816898, 0.566806, 0.483600, + 0.817752, 0.570200, 0.482748, + 0.818608, 0.573611, 0.481898, + 0.819464, 0.577019, 0.481035, + 0.820320, 0.580426, 0.480189, + 0.821177, 0.583832, 0.479337, + 0.822036, 0.587241, 0.478479, + 0.822888, 0.590654, 0.477626, + 0.823741, 0.594071, 0.476774, + 0.824596, 0.597489, 0.475924, + 0.825452, 0.600903, 0.475075, + 0.826310, 0.604330, 0.474213, + 0.827167, 0.607752, 0.473350, + 0.828020, 0.611173, 0.472504, + 0.828883, 0.614590, 0.471655, + 0.829740, 0.618022, 0.470796, + 0.830598, 0.621451, 0.469943, + 0.831459, 0.624886, 0.469087, + 0.832315, 0.628325, 0.468218, + 0.833174, 0.631759, 0.467368, + 0.834038, 0.635197, 0.466506, + 0.834897, 0.638641, 0.465638, + 0.835759, 0.642088, 0.464790, + 0.836622, 0.645532, 0.463931, + 0.837488, 0.648990, 0.463055, + 0.838348, 0.652439, 0.462201, + 0.839214, 0.655902, 0.461342, + 0.840083, 0.659357, 0.460469, + 0.840947, 0.662826, 0.459614, + 0.841815, 0.666286, 0.458749, + 0.842684, 0.669764, 0.457878, + 0.843548, 0.673236, 0.457012, + 0.844421, 0.676714, 0.456145, + 0.845291, 0.680187, 0.455282, + 0.846160, 0.683675, 0.454415, + 0.847033, 0.687166, 0.453536, + 0.847907, 0.690654, 0.452675, + 0.848784, 0.694149, 0.451800, + 0.849662, 0.697652, 0.450924, + 0.850534, 0.701158, 0.450049, + 0.851410, 0.704667, 0.449178, + 0.852296, 0.708180, 0.448296, + 0.853170, 0.711699, 0.447413, + 0.854049, 0.715220, 0.446541, + 0.854936, 0.718742, 0.445655, + 0.855818, 0.722269, 0.444788, + 0.856699, 0.725811, 0.443905, + 0.857584, 0.729347, 0.443021, + 0.858470, 0.732893, 0.442142, + 0.859359, 0.736436, 0.441247, + 0.860250, 0.739997, 0.440361, + 0.861136, 0.743552, 0.439474, + 0.862032, 0.747115, 0.438584, + 0.862924, 0.750684, 0.437706, + 0.863818, 0.754257, 0.436810, + 0.864708, 0.757833, 0.435919, + 0.865604, 0.761413, 0.435028, + 0.866502, 0.765006, 0.434120, + 0.867400, 0.768593, 0.433228, + 0.868307, 0.772195, 0.432343, + 0.869206, 0.775798, 0.431443, + 0.870103, 0.779408, 0.430538, + 0.871012, 0.783023, 0.429635, + 0.871923, 0.786651, 0.428733, + 0.872831, 0.790273, 0.427834, + 0.873742, 0.793911, 0.426929, + 0.874658, 0.797545, 0.426015, + 0.875582, 0.801192, 0.425119, + 0.876504, 0.804847, 0.424205, + 0.877438, 0.808510, 0.423294, + 0.878381, 0.812177, 0.422386, + 0.879330, 0.815859, 0.421480, + 0.880295, 0.819541, 0.420578, + 0.881278, 0.823243, 0.419683, + 0.882276, 0.826956, 0.418775, + 0.883302, 0.830680, 0.417880, + 0.884356, 0.834420, 0.416995, + 0.885442, 0.838174, 0.416101, + 0.886573, 0.841950, 0.415222, + 0.887744, 0.845741, 0.414352, + 0.888981, 0.849563, 0.413497, + 0.890275, 0.853401, 0.412658, + 0.891647, 0.857274, 0.411817, + 0.893098, 0.861176, 0.411008, + 0.894649, 0.865109, 0.410221, + 0.896296, 0.869084, 0.409443, + 0.898055, 0.873088, 0.408695, + 0.899941, 0.877132, 0.407976, + 0.901952, 0.881224, 0.407286, + 0.904103, 0.885355, 0.406631, + 0.906404, 0.889529, 0.406013, + 0.908850, 0.893747, 0.405420, + 0.911455, 0.898012, 0.404859, + 0.914220, 0.902322, 0.404346, + 0.917142, 0.906675, 0.403876, + 0.920217, 0.911070, 0.403439, + 0.923457, 0.915502, 0.403034, + 0.926841, 0.919982, 0.402665, + 0.930380, 0.924494, 0.402333, + 0.934052, 0.929044, 0.402037, + 0.937866, 0.933626, 0.401778, + 0.941799, 0.938244, 0.401552, + 0.945848, 0.942888, 0.401355, + 0.950004, 0.947555, 0.401183, + 0.954258, 0.952243, 0.401033, + 0.958599, 0.956957, 0.400902, + 0.963014, 0.961688, 0.400787, + 0.967502, 0.966439, 0.400686, + 0.972046, 0.971205, 0.400598, + 0.976641, 0.975983, 0.400519, + 0.981286, 0.980779, 0.400448, + 0.985967, 0.985584, 0.400383, + 0.990680, 0.990397, 0.400321, + 0.995418, 0.995218, 0.400262, + 1.000000, 1.000000, 0.400203, +}; + +const float ColorMap::m_devon[m_size] = +{ + 0.171032, 0.100402, 0.299782, + 0.170868, 0.104144, 0.303372, + 0.170677, 0.107856, 0.306989, + 0.170463, 0.111594, 0.310614, + 0.170227, 0.115240, 0.314216, + 0.169972, 0.118939, 0.317840, + 0.169698, 0.122543, 0.321462, + 0.169404, 0.126240, 0.325088, + 0.169084, 0.129892, 0.328738, + 0.168737, 0.133501, 0.332383, + 0.168373, 0.137129, 0.336012, + 0.168007, 0.140767, 0.339673, + 0.167646, 0.144378, 0.343319, + 0.167278, 0.147990, 0.346977, + 0.166888, 0.151600, 0.350639, + 0.166476, 0.155235, 0.354294, + 0.166051, 0.158875, 0.357969, + 0.165623, 0.162508, 0.361639, + 0.165203, 0.166121, 0.365312, + 0.164797, 0.169787, 0.369002, + 0.164391, 0.173411, 0.372682, + 0.163968, 0.177075, 0.376391, + 0.163527, 0.180716, 0.380085, + 0.163081, 0.184398, 0.383795, + 0.162637, 0.188101, 0.387502, + 0.162198, 0.191754, 0.391238, + 0.161760, 0.195449, 0.394962, + 0.161310, 0.199141, 0.398700, + 0.160837, 0.202866, 0.402443, + 0.160362, 0.206620, 0.406214, + 0.159908, 0.210329, 0.409984, + 0.159471, 0.214084, 0.413758, + 0.159039, 0.217839, 0.417555, + 0.158601, 0.221601, 0.421349, + 0.158144, 0.225384, 0.425181, + 0.157676, 0.229179, 0.429013, + 0.157228, 0.232977, 0.432870, + 0.156806, 0.236829, 0.436744, + 0.156386, 0.240632, 0.440631, + 0.155952, 0.244485, 0.444564, + 0.155517, 0.248387, 0.448507, + 0.155097, 0.252261, 0.452491, + 0.154694, 0.256148, 0.456492, + 0.154309, 0.260084, 0.460536, + 0.153943, 0.264033, 0.464642, + 0.153600, 0.267966, 0.468777, + 0.153286, 0.271942, 0.472958, + 0.153005, 0.275975, 0.477209, + 0.152762, 0.279975, 0.481516, + 0.152563, 0.284007, 0.485886, + 0.152415, 0.288059, 0.490337, + 0.152323, 0.292137, 0.494857, + 0.152295, 0.296219, 0.499444, + 0.152339, 0.300310, 0.504136, + 0.152463, 0.304414, 0.508899, + 0.152674, 0.308529, 0.513749, + 0.152981, 0.312618, 0.518688, + 0.153392, 0.316727, 0.523706, + 0.153915, 0.320817, 0.528817, + 0.154555, 0.324864, 0.533993, + 0.155323, 0.328919, 0.539260, + 0.156229, 0.332926, 0.544598, + 0.157206, 0.336879, 0.549998, + 0.158378, 0.340797, 0.555448, + 0.159616, 0.344655, 0.560957, + 0.161055, 0.348463, 0.566511, + 0.162589, 0.352195, 0.572090, + 0.164258, 0.355879, 0.577689, + 0.166003, 0.359470, 0.583313, + 0.167904, 0.362993, 0.588941, + 0.169932, 0.366457, 0.594581, + 0.172025, 0.369823, 0.600212, + 0.174249, 0.373130, 0.605830, + 0.176531, 0.376379, 0.611449, + 0.178949, 0.379540, 0.617045, + 0.181403, 0.382648, 0.622622, + 0.183976, 0.385696, 0.628190, + 0.186619, 0.388711, 0.633736, + 0.189341, 0.391669, 0.639262, + 0.192134, 0.394587, 0.644771, + 0.195027, 0.397481, 0.650276, + 0.197982, 0.400359, 0.655767, + 0.201030, 0.403213, 0.661243, + 0.204231, 0.406065, 0.666711, + 0.207483, 0.408906, 0.672184, + 0.210863, 0.411761, 0.677651, + 0.214378, 0.414631, 0.683108, + 0.218033, 0.417528, 0.688571, + 0.221826, 0.420436, 0.694021, + 0.225816, 0.423384, 0.699481, + 0.229930, 0.426373, 0.704939, + 0.234292, 0.429408, 0.710390, + 0.238813, 0.432492, 0.715836, + 0.243553, 0.435617, 0.721257, + 0.248547, 0.438782, 0.726672, + 0.253725, 0.442028, 0.732066, + 0.259152, 0.445303, 0.737422, + 0.264778, 0.448649, 0.742750, + 0.270677, 0.452043, 0.748029, + 0.276773, 0.455480, 0.753250, + 0.283095, 0.458971, 0.758422, + 0.289622, 0.462495, 0.763516, + 0.296351, 0.466068, 0.768535, + 0.303257, 0.469688, 0.773474, + 0.310367, 0.473307, 0.778324, + 0.317597, 0.476974, 0.783072, + 0.324970, 0.480647, 0.787721, + 0.332494, 0.484334, 0.792267, + 0.340093, 0.488042, 0.796701, + 0.347786, 0.491739, 0.801030, + 0.355555, 0.495425, 0.805247, + 0.363359, 0.499108, 0.809363, + 0.371217, 0.502778, 0.813363, + 0.379113, 0.506438, 0.817267, + 0.387014, 0.510082, 0.821072, + 0.394935, 0.513709, 0.824780, + 0.402847, 0.517310, 0.828402, + 0.410758, 0.520881, 0.831943, + 0.418634, 0.524436, 0.835398, + 0.426504, 0.527966, 0.838782, + 0.434346, 0.531477, 0.842105, + 0.442172, 0.534964, 0.845359, + 0.449948, 0.538437, 0.848559, + 0.457695, 0.541872, 0.851707, + 0.465406, 0.545307, 0.854810, + 0.473085, 0.548724, 0.857863, + 0.480729, 0.552119, 0.860879, + 0.488341, 0.555493, 0.863862, + 0.495894, 0.558869, 0.866797, + 0.503414, 0.562249, 0.869705, + 0.510895, 0.565597, 0.872582, + 0.518335, 0.568956, 0.875424, + 0.525716, 0.572320, 0.878233, + 0.533049, 0.575682, 0.881008, + 0.540328, 0.579042, 0.883754, + 0.547548, 0.582405, 0.886461, + 0.554710, 0.585792, 0.889130, + 0.561804, 0.589169, 0.891760, + 0.568813, 0.592583, 0.894351, + 0.575760, 0.595989, 0.896895, + 0.582600, 0.599423, 0.899390, + 0.589354, 0.602864, 0.901830, + 0.596014, 0.606322, 0.904217, + 0.602558, 0.609800, 0.906550, + 0.608993, 0.613288, 0.908815, + 0.615285, 0.616803, 0.911017, + 0.621456, 0.620324, 0.913150, + 0.627490, 0.623854, 0.915206, + 0.633377, 0.627389, 0.917197, + 0.639110, 0.630941, 0.919099, + 0.644686, 0.634493, 0.920929, + 0.650114, 0.638043, 0.922685, + 0.655374, 0.641594, 0.924355, + 0.660476, 0.645145, 0.925951, + 0.665423, 0.648695, 0.927463, + 0.670216, 0.652234, 0.928904, + 0.674845, 0.655767, 0.930274, + 0.679329, 0.659281, 0.931567, + 0.683675, 0.662794, 0.932793, + 0.687888, 0.666281, 0.933957, + 0.691973, 0.669769, 0.935062, + 0.695936, 0.673235, 0.936114, + 0.699783, 0.676690, 0.937110, + 0.703538, 0.680123, 0.938058, + 0.707197, 0.683555, 0.938964, + 0.710775, 0.686972, 0.939834, + 0.714271, 0.690376, 0.940666, + 0.717713, 0.693771, 0.941466, + 0.721083, 0.697160, 0.942246, + 0.724414, 0.700543, 0.942999, + 0.727695, 0.703915, 0.943730, + 0.730940, 0.707284, 0.944446, + 0.734158, 0.710651, 0.945148, + 0.737345, 0.714009, 0.945832, + 0.740512, 0.717375, 0.946509, + 0.743663, 0.720725, 0.947182, + 0.746797, 0.724085, 0.947844, + 0.749918, 0.727443, 0.948500, + 0.753034, 0.730802, 0.949152, + 0.756148, 0.734165, 0.949802, + 0.759251, 0.737524, 0.950450, + 0.762355, 0.740887, 0.951095, + 0.765464, 0.744257, 0.951736, + 0.768558, 0.747631, 0.952378, + 0.771667, 0.751005, 0.953024, + 0.774765, 0.754380, 0.953665, + 0.777876, 0.757757, 0.954305, + 0.780981, 0.761139, 0.954947, + 0.784096, 0.764526, 0.955591, + 0.787207, 0.767912, 0.956232, + 0.790319, 0.771312, 0.956872, + 0.793444, 0.774703, 0.957517, + 0.796559, 0.778108, 0.958163, + 0.799691, 0.781515, 0.958806, + 0.802814, 0.784924, 0.959450, + 0.805948, 0.788334, 0.960097, + 0.809088, 0.791749, 0.960744, + 0.812223, 0.795169, 0.961389, + 0.815367, 0.798594, 0.962035, + 0.818510, 0.802020, 0.962686, + 0.821666, 0.805450, 0.963336, + 0.824815, 0.808891, 0.963984, + 0.827972, 0.812327, 0.964634, + 0.831138, 0.815773, 0.965286, + 0.834302, 0.819214, 0.965939, + 0.837470, 0.822670, 0.966593, + 0.840640, 0.826123, 0.967249, + 0.843810, 0.829585, 0.967905, + 0.846989, 0.833043, 0.968558, + 0.850174, 0.836510, 0.969212, + 0.853356, 0.839984, 0.969868, + 0.856547, 0.843451, 0.970526, + 0.859742, 0.846929, 0.971184, + 0.862940, 0.850412, 0.971844, + 0.866137, 0.853895, 0.972506, + 0.869340, 0.857386, 0.973165, + 0.872548, 0.860879, 0.973823, + 0.875758, 0.864379, 0.974484, + 0.878969, 0.867881, 0.975146, + 0.882187, 0.871384, 0.975809, + 0.885409, 0.874890, 0.976473, + 0.888635, 0.878403, 0.977140, + 0.891863, 0.881920, 0.977804, + 0.895095, 0.885439, 0.978468, + 0.898326, 0.888964, 0.979137, + 0.901566, 0.892492, 0.979807, + 0.904809, 0.896022, 0.980474, + 0.908057, 0.899559, 0.981142, + 0.911303, 0.903098, 0.981813, + 0.914556, 0.906639, 0.982484, + 0.917813, 0.910187, 0.983151, + 0.921066, 0.913737, 0.983823, + 0.924330, 0.917292, 0.984498, + 0.927593, 0.920843, 0.985170, + 0.930866, 0.924406, 0.985842, + 0.934133, 0.927970, 0.986516, + 0.937412, 0.931540, 0.987191, + 0.940689, 0.935113, 0.987862, + 0.943968, 0.938690, 0.988536, + 0.947251, 0.942272, 0.989213, + 0.950534, 0.945851, 0.989888, + 0.953821, 0.949437, 0.990561, + 0.957106, 0.953030, 0.991236, + 0.960399, 0.956621, 0.991911, + 0.963687, 0.960219, 0.992587, + 0.966981, 0.963815, 0.993262, + 0.970273, 0.967421, 0.993933, + 0.973568, 0.971024, 0.994603, + 0.976862, 0.974631, 0.995274, + 0.980158, 0.978242, 0.995945, + 0.983450, 0.981861, 0.996615, + 0.986748, 0.985477, 0.997285, + 0.990040, 0.989098, 0.997954, + 0.993335, 0.992721, 0.998623, + 0.996621, 0.996340, 0.999290, + 0.999916, 0.999970, 0.999952, +}; + +const float ColorMap::m_lajolla[m_size] = +{ + 0.999831, 0.999745, 0.799907, + 0.999529, 0.997249, 0.792918, + 0.999208, 0.994757, 0.785931, + 0.998869, 0.992265, 0.778940, + 0.998513, 0.989768, 0.771954, + 0.998141, 0.987268, 0.764967, + 0.997753, 0.984763, 0.757977, + 0.997350, 0.982252, 0.750989, + 0.996933, 0.979734, 0.743991, + 0.996501, 0.977208, 0.736995, + 0.996056, 0.974673, 0.729998, + 0.995597, 0.972134, 0.722989, + 0.995124, 0.969577, 0.715989, + 0.994638, 0.967011, 0.708976, + 0.994140, 0.964426, 0.701948, + 0.993629, 0.961826, 0.694924, + 0.993104, 0.959212, 0.687894, + 0.992564, 0.956574, 0.680846, + 0.992011, 0.953914, 0.673801, + 0.991445, 0.951226, 0.666736, + 0.990867, 0.948508, 0.659670, + 0.990276, 0.945762, 0.652583, + 0.989672, 0.942984, 0.645487, + 0.989053, 0.940166, 0.638383, + 0.988417, 0.937306, 0.631265, + 0.987770, 0.934399, 0.624131, + 0.987110, 0.931449, 0.616981, + 0.986430, 0.928445, 0.609814, + 0.985734, 0.925390, 0.602638, + 0.985024, 0.922276, 0.595448, + 0.984295, 0.919090, 0.588241, + 0.983544, 0.915842, 0.581031, + 0.982780, 0.912528, 0.573808, + 0.981996, 0.909132, 0.566581, + 0.981188, 0.905665, 0.559340, + 0.980362, 0.902106, 0.552106, + 0.979515, 0.898463, 0.544864, + 0.978640, 0.894738, 0.537636, + 0.977749, 0.890912, 0.530411, + 0.976833, 0.886997, 0.523209, + 0.975892, 0.882982, 0.516016, + 0.974929, 0.878873, 0.508878, + 0.973943, 0.874665, 0.501764, + 0.972936, 0.870355, 0.494698, + 0.971900, 0.865954, 0.487691, + 0.970841, 0.861451, 0.480735, + 0.969761, 0.856853, 0.473869, + 0.968661, 0.852169, 0.467098, + 0.967540, 0.847384, 0.460403, + 0.966394, 0.842526, 0.453838, + 0.965232, 0.837582, 0.447383, + 0.964054, 0.832560, 0.441065, + 0.962864, 0.827471, 0.434901, + 0.961653, 0.822324, 0.428874, + 0.960439, 0.817114, 0.423009, + 0.959208, 0.811859, 0.417337, + 0.957973, 0.806564, 0.411826, + 0.956727, 0.801228, 0.406515, + 0.955483, 0.795868, 0.401394, + 0.954233, 0.790491, 0.396470, + 0.952985, 0.785103, 0.391761, + 0.951734, 0.779703, 0.387244, + 0.950493, 0.774305, 0.382955, + 0.949252, 0.768915, 0.378860, + 0.948022, 0.763539, 0.374977, + 0.946797, 0.758183, 0.371295, + 0.945583, 0.752838, 0.367823, + 0.944379, 0.747533, 0.364549, + 0.943186, 0.742247, 0.361472, + 0.942003, 0.736993, 0.358570, + 0.940832, 0.731775, 0.355871, + 0.939675, 0.726590, 0.353323, + 0.938529, 0.721440, 0.350960, + 0.937397, 0.716337, 0.348738, + 0.936279, 0.711264, 0.346674, + 0.935167, 0.706227, 0.344750, + 0.934070, 0.701224, 0.342973, + 0.932986, 0.696264, 0.341304, + 0.931915, 0.691330, 0.339767, + 0.930857, 0.686438, 0.338316, + 0.929804, 0.681570, 0.336993, + 0.928760, 0.676746, 0.335755, + 0.927727, 0.671938, 0.334613, + 0.926704, 0.667161, 0.333537, + 0.925689, 0.662415, 0.332545, + 0.924676, 0.657688, 0.331596, + 0.923678, 0.652971, 0.330728, + 0.922679, 0.648286, 0.329931, + 0.921685, 0.643617, 0.329173, + 0.920691, 0.638968, 0.328448, + 0.919708, 0.634336, 0.327769, + 0.918721, 0.629704, 0.327130, + 0.917745, 0.625092, 0.326525, + 0.916762, 0.620494, 0.325953, + 0.915774, 0.615891, 0.325408, + 0.914796, 0.611306, 0.324889, + 0.913814, 0.606722, 0.324391, + 0.912824, 0.602139, 0.323912, + 0.911832, 0.597565, 0.323453, + 0.910837, 0.592994, 0.323010, + 0.909834, 0.588408, 0.322574, + 0.908821, 0.583836, 0.322140, + 0.907806, 0.579265, 0.321715, + 0.906775, 0.574674, 0.321308, + 0.905735, 0.570090, 0.320914, + 0.904677, 0.565498, 0.320521, + 0.903607, 0.560904, 0.320125, + 0.902520, 0.556296, 0.319729, + 0.901411, 0.551691, 0.319336, + 0.900282, 0.547063, 0.318947, + 0.899129, 0.542431, 0.318559, + 0.897945, 0.537786, 0.318170, + 0.896736, 0.533119, 0.317781, + 0.895488, 0.528446, 0.317388, + 0.894206, 0.523753, 0.316994, + 0.892880, 0.519049, 0.316599, + 0.891511, 0.514322, 0.316201, + 0.890091, 0.509569, 0.315793, + 0.888622, 0.504806, 0.315370, + 0.887088, 0.500007, 0.314938, + 0.885494, 0.495205, 0.314507, + 0.883832, 0.490372, 0.314076, + 0.882090, 0.485505, 0.313632, + 0.880268, 0.480622, 0.313167, + 0.878363, 0.475721, 0.312685, + 0.876360, 0.470784, 0.312193, + 0.874260, 0.465813, 0.311698, + 0.872057, 0.460829, 0.311198, + 0.869732, 0.455822, 0.310676, + 0.867292, 0.450788, 0.310126, + 0.864725, 0.445721, 0.309559, + 0.862029, 0.440643, 0.308972, + 0.859184, 0.435556, 0.308348, + 0.856198, 0.430436, 0.307704, + 0.853059, 0.425310, 0.307055, + 0.849766, 0.420166, 0.306384, + 0.846302, 0.415023, 0.305675, + 0.842682, 0.409886, 0.304924, + 0.838883, 0.404735, 0.304148, + 0.834916, 0.399603, 0.303343, + 0.830773, 0.394500, 0.302509, + 0.826450, 0.389415, 0.301644, + 0.821954, 0.384356, 0.300746, + 0.817275, 0.379341, 0.299821, + 0.812425, 0.374378, 0.298850, + 0.807406, 0.369452, 0.297832, + 0.802212, 0.364595, 0.296800, + 0.796857, 0.359813, 0.295702, + 0.791346, 0.355117, 0.294575, + 0.785683, 0.350488, 0.293413, + 0.779869, 0.345935, 0.292218, + 0.773918, 0.341509, 0.290978, + 0.767839, 0.337176, 0.289694, + 0.761640, 0.332954, 0.288366, + 0.755332, 0.328832, 0.286993, + 0.748910, 0.324813, 0.285587, + 0.742404, 0.320940, 0.284148, + 0.735801, 0.317163, 0.282680, + 0.729129, 0.313515, 0.281127, + 0.722383, 0.309983, 0.279578, + 0.715588, 0.306561, 0.277960, + 0.708732, 0.303235, 0.276314, + 0.701821, 0.300045, 0.274597, + 0.694882, 0.296965, 0.272862, + 0.687913, 0.293960, 0.271085, + 0.680906, 0.291083, 0.269266, + 0.673889, 0.288276, 0.267363, + 0.666846, 0.285557, 0.265463, + 0.659797, 0.282950, 0.263515, + 0.652729, 0.280375, 0.261494, + 0.645660, 0.277907, 0.259453, + 0.638589, 0.275496, 0.257342, + 0.631514, 0.273125, 0.255206, + 0.624438, 0.270823, 0.253003, + 0.617360, 0.268553, 0.250756, + 0.610287, 0.266332, 0.248485, + 0.603222, 0.264149, 0.246122, + 0.596156, 0.261987, 0.243734, + 0.589093, 0.259866, 0.241320, + 0.582044, 0.257747, 0.238831, + 0.575000, 0.255668, 0.236327, + 0.567965, 0.253604, 0.233732, + 0.560934, 0.251554, 0.231138, + 0.553914, 0.249483, 0.228487, + 0.546904, 0.247454, 0.225780, + 0.539894, 0.245396, 0.223036, + 0.532906, 0.243360, 0.220254, + 0.525921, 0.241340, 0.217418, + 0.518950, 0.239301, 0.214548, + 0.511977, 0.237280, 0.211665, + 0.505025, 0.235233, 0.208715, + 0.498095, 0.233152, 0.205757, + 0.491166, 0.231122, 0.202744, + 0.484232, 0.229060, 0.199703, + 0.477332, 0.226999, 0.196690, + 0.470446, 0.224903, 0.193599, + 0.463562, 0.222859, 0.190481, + 0.456701, 0.220788, 0.187383, + 0.449858, 0.218684, 0.184220, + 0.443028, 0.216604, 0.181049, + 0.436213, 0.214490, 0.177923, + 0.429412, 0.212397, 0.174725, + 0.422622, 0.210282, 0.171513, + 0.415865, 0.208176, 0.168312, + 0.409121, 0.206083, 0.165094, + 0.402387, 0.203968, 0.161932, + 0.395693, 0.201818, 0.158717, + 0.389005, 0.199696, 0.155501, + 0.382326, 0.197597, 0.152278, + 0.375682, 0.195474, 0.149098, + 0.369063, 0.193367, 0.145930, + 0.362455, 0.191238, 0.142740, + 0.355879, 0.189133, 0.139537, + 0.349312, 0.187021, 0.136394, + 0.342780, 0.184917, 0.133292, + 0.336248, 0.182782, 0.130208, + 0.329771, 0.180679, 0.127046, + 0.323293, 0.178608, 0.123972, + 0.316844, 0.176475, 0.120915, + 0.310431, 0.174411, 0.117925, + 0.304013, 0.172305, 0.114880, + 0.297642, 0.170234, 0.111957, + 0.291301, 0.168140, 0.108996, + 0.284955, 0.166067, 0.106101, + 0.278670, 0.164036, 0.103209, + 0.272374, 0.161969, 0.100318, + 0.266143, 0.159860, 0.097520, + 0.259913, 0.157833, 0.094764, + 0.253709, 0.155804, 0.092001, + 0.247534, 0.153732, 0.089260, + 0.241379, 0.151698, 0.086567, + 0.235263, 0.149701, 0.083951, + 0.229142, 0.147663, 0.081329, + 0.223074, 0.145659, 0.078687, + 0.217021, 0.143616, 0.076120, + 0.211005, 0.141605, 0.073581, + 0.205032, 0.139543, 0.070837, + 0.199089, 0.137586, 0.068084, + 0.193222, 0.135533, 0.065213, + 0.187395, 0.133541, 0.062323, + 0.181558, 0.131530, 0.059337, + 0.175797, 0.129510, 0.056198, + 0.170114, 0.127477, 0.052899, + 0.164454, 0.125481, 0.049640, + 0.158832, 0.123421, 0.046062, + 0.153229, 0.121394, 0.042482, + 0.147732, 0.119395, 0.038691, + 0.142251, 0.117348, 0.034740, + 0.136816, 0.115319, 0.030784, + 0.131463, 0.113321, 0.026943, + 0.126157, 0.111255, 0.023110, + 0.120855, 0.109198, 0.019283, + 0.115699, 0.107134, 0.015460, + 0.110584, 0.104992, 0.011622, + 0.105487, 0.102956, 0.007624, + 0.100227, 0.100908, 0.003791, +}; + +const float ColorMap::m_bamako[m_size] = +{ + 0.001175, 0.250044, 0.300000, + 0.003900, 0.251568, 0.298605, + 0.006602, 0.253054, 0.297219, + 0.009291, 0.254561, 0.295808, + 0.012175, 0.256038, 0.294402, + 0.014801, 0.257549, 0.292999, + 0.017450, 0.259071, 0.291607, + 0.020096, 0.260569, 0.290178, + 0.022743, 0.262082, 0.288777, + 0.025398, 0.263613, 0.287345, + 0.028064, 0.265111, 0.285921, + 0.030746, 0.266642, 0.284503, + 0.033437, 0.268163, 0.283091, + 0.036369, 0.269714, 0.281652, + 0.039136, 0.271239, 0.280209, + 0.041941, 0.272776, 0.278785, + 0.044597, 0.274322, 0.277340, + 0.047216, 0.275891, 0.275905, + 0.049816, 0.277433, 0.274432, + 0.052305, 0.278996, 0.272982, + 0.054846, 0.280535, 0.271512, + 0.057331, 0.282129, 0.270069, + 0.059903, 0.283690, 0.268596, + 0.062324, 0.285258, 0.267103, + 0.064737, 0.286842, 0.265642, + 0.067177, 0.288441, 0.264165, + 0.069647, 0.290030, 0.262671, + 0.072007, 0.291645, 0.261177, + 0.074435, 0.293235, 0.259690, + 0.076803, 0.294845, 0.258168, + 0.079232, 0.296472, 0.256672, + 0.081738, 0.298081, 0.255176, + 0.084163, 0.299722, 0.253651, + 0.086556, 0.301341, 0.252132, + 0.089008, 0.302979, 0.250592, + 0.091487, 0.304633, 0.249073, + 0.093906, 0.306298, 0.247540, + 0.096327, 0.307931, 0.245981, + 0.098845, 0.309614, 0.244430, + 0.101320, 0.311270, 0.242884, + 0.103840, 0.312940, 0.241344, + 0.106373, 0.314614, 0.239778, + 0.108845, 0.316315, 0.238209, + 0.111400, 0.317998, 0.236658, + 0.113913, 0.319699, 0.235086, + 0.116485, 0.321393, 0.233469, + 0.119038, 0.323111, 0.231914, + 0.121564, 0.324810, 0.230295, + 0.124158, 0.326529, 0.228728, + 0.126757, 0.328264, 0.227119, + 0.129375, 0.330003, 0.225511, + 0.132004, 0.331730, 0.223888, + 0.134649, 0.333485, 0.222278, + 0.137276, 0.335240, 0.220682, + 0.139884, 0.336985, 0.219039, + 0.142577, 0.338745, 0.217408, + 0.145276, 0.340514, 0.215777, + 0.147932, 0.342290, 0.214132, + 0.150622, 0.344055, 0.212483, + 0.153312, 0.345842, 0.210827, + 0.156069, 0.347650, 0.209167, + 0.158791, 0.349444, 0.207513, + 0.161545, 0.351250, 0.205851, + 0.164291, 0.353061, 0.204188, + 0.167053, 0.354889, 0.202479, + 0.169827, 0.356708, 0.200784, + 0.172592, 0.358526, 0.199098, + 0.175396, 0.360362, 0.197423, + 0.178238, 0.362218, 0.195717, + 0.181022, 0.364063, 0.194034, + 0.183870, 0.365930, 0.192298, + 0.186724, 0.367787, 0.190577, + 0.189589, 0.369663, 0.188866, + 0.192463, 0.371540, 0.187139, + 0.195352, 0.373435, 0.185419, + 0.198249, 0.375327, 0.183644, + 0.201156, 0.377240, 0.181885, + 0.204127, 0.379148, 0.180139, + 0.207065, 0.381078, 0.178409, + 0.210008, 0.383003, 0.176605, + 0.212971, 0.384930, 0.174859, + 0.215989, 0.386875, 0.173056, + 0.218980, 0.388843, 0.171271, + 0.221986, 0.390806, 0.169504, + 0.225012, 0.392773, 0.167676, + 0.228091, 0.394757, 0.165848, + 0.231153, 0.396745, 0.164075, + 0.234233, 0.398752, 0.162241, + 0.237349, 0.400781, 0.160365, + 0.240427, 0.402789, 0.158567, + 0.243566, 0.404820, 0.156711, + 0.246728, 0.406871, 0.154836, + 0.249887, 0.408927, 0.152959, + 0.253098, 0.410998, 0.151093, + 0.256293, 0.413082, 0.149225, + 0.259543, 0.415165, 0.147333, + 0.262784, 0.417278, 0.145458, + 0.266059, 0.419392, 0.143520, + 0.269354, 0.421510, 0.141607, + 0.272646, 0.423655, 0.139630, + 0.276003, 0.425815, 0.137750, + 0.279354, 0.427992, 0.135746, + 0.282735, 0.430174, 0.133822, + 0.286111, 0.432382, 0.131850, + 0.289556, 0.434588, 0.129889, + 0.292997, 0.436821, 0.127876, + 0.296483, 0.439056, 0.125885, + 0.299981, 0.441323, 0.123822, + 0.303503, 0.443605, 0.121787, + 0.307065, 0.445890, 0.119770, + 0.310662, 0.448206, 0.117731, + 0.314258, 0.450539, 0.115679, + 0.317900, 0.452889, 0.113616, + 0.321563, 0.455253, 0.111528, + 0.325257, 0.457630, 0.109445, + 0.329005, 0.460030, 0.107308, + 0.332768, 0.462451, 0.105131, + 0.336543, 0.464897, 0.103037, + 0.340375, 0.467359, 0.100847, + 0.344219, 0.469841, 0.098693, + 0.348122, 0.472335, 0.096453, + 0.352037, 0.474856, 0.094325, + 0.356012, 0.477383, 0.092102, + 0.360001, 0.479944, 0.089849, + 0.364033, 0.482513, 0.087617, + 0.368109, 0.485098, 0.085276, + 0.372215, 0.487718, 0.082993, + 0.376382, 0.490337, 0.080686, + 0.380573, 0.492964, 0.078304, + 0.384799, 0.495619, 0.075955, + 0.389090, 0.498292, 0.073656, + 0.393410, 0.500954, 0.071224, + 0.397790, 0.503623, 0.068802, + 0.402200, 0.506297, 0.066264, + 0.406682, 0.508981, 0.063774, + 0.411203, 0.511641, 0.061172, + 0.415776, 0.514308, 0.058651, + 0.420400, 0.516946, 0.056070, + 0.425087, 0.519560, 0.053359, + 0.429814, 0.522143, 0.050712, + 0.434597, 0.524702, 0.047969, + 0.439428, 0.527215, 0.045272, + 0.444319, 0.529673, 0.042483, + 0.449245, 0.532071, 0.039697, + 0.454215, 0.534399, 0.036906, + 0.459225, 0.536663, 0.034001, + 0.464275, 0.538835, 0.031435, + 0.469349, 0.540915, 0.028957, + 0.474442, 0.542911, 0.026597, + 0.479560, 0.544799, 0.024363, + 0.484680, 0.546591, 0.022265, + 0.489820, 0.548275, 0.020312, + 0.494971, 0.549847, 0.018512, + 0.500103, 0.551321, 0.016876, + 0.505242, 0.552694, 0.015412, + 0.510378, 0.553974, 0.014132, + 0.515503, 0.555166, 0.013033, + 0.520629, 0.556283, 0.012180, + 0.525754, 0.557353, 0.011416, + 0.530877, 0.558348, 0.010839, + 0.536006, 0.559331, 0.010585, + 0.541151, 0.560295, 0.010612, + 0.546332, 0.561256, 0.010945, + 0.551529, 0.562255, 0.011649, + 0.556773, 0.563285, 0.012516, + 0.562073, 0.564377, 0.013650, + 0.567425, 0.565550, 0.015118, + 0.572854, 0.566844, 0.016927, + 0.578351, 0.568243, 0.019098, + 0.583945, 0.569784, 0.021653, + 0.589625, 0.571485, 0.024617, + 0.595411, 0.573356, 0.028014, + 0.601291, 0.575400, 0.031870, + 0.607281, 0.577626, 0.036408, + 0.613352, 0.580062, 0.041287, + 0.619542, 0.582679, 0.046299, + 0.625810, 0.585515, 0.051565, + 0.632175, 0.588528, 0.057023, + 0.638620, 0.591759, 0.062625, + 0.645137, 0.595166, 0.068288, + 0.651731, 0.598763, 0.074092, + 0.658372, 0.602535, 0.079969, + 0.665062, 0.606473, 0.085984, + 0.671795, 0.610568, 0.092200, + 0.678556, 0.614798, 0.098456, + 0.685338, 0.619175, 0.104760, + 0.692129, 0.623659, 0.111287, + 0.698910, 0.628247, 0.117832, + 0.705693, 0.632925, 0.124466, + 0.712448, 0.637686, 0.131249, + 0.719184, 0.642515, 0.138104, + 0.725880, 0.647397, 0.145035, + 0.732527, 0.652321, 0.152009, + 0.739120, 0.657282, 0.159119, + 0.745640, 0.662259, 0.166286, + 0.752096, 0.667240, 0.173524, + 0.758470, 0.672228, 0.180821, + 0.764752, 0.677207, 0.188226, + 0.770940, 0.682154, 0.195617, + 0.777025, 0.687087, 0.203085, + 0.782992, 0.691986, 0.210591, + 0.788855, 0.696837, 0.218132, + 0.794593, 0.701640, 0.225696, + 0.800210, 0.706402, 0.233246, + 0.805697, 0.711100, 0.240836, + 0.811064, 0.715739, 0.248452, + 0.816305, 0.720308, 0.256008, + 0.821416, 0.724823, 0.263607, + 0.826404, 0.729264, 0.271154, + 0.831274, 0.733644, 0.278697, + 0.836021, 0.737953, 0.286192, + 0.840659, 0.742207, 0.293686, + 0.845186, 0.746391, 0.301143, + 0.849615, 0.750519, 0.308586, + 0.853939, 0.754588, 0.315983, + 0.858179, 0.758596, 0.323333, + 0.862341, 0.762550, 0.330648, + 0.866414, 0.766461, 0.337937, + 0.870416, 0.770323, 0.345196, + 0.874359, 0.774139, 0.352412, + 0.878242, 0.777923, 0.359601, + 0.882069, 0.781666, 0.366759, + 0.885849, 0.785374, 0.373882, + 0.889582, 0.789052, 0.380980, + 0.893277, 0.792699, 0.388036, + 0.896942, 0.796319, 0.395081, + 0.900568, 0.799924, 0.402087, + 0.904169, 0.803498, 0.409089, + 0.907751, 0.807061, 0.416060, + 0.911302, 0.810597, 0.423005, + 0.914836, 0.814123, 0.429945, + 0.918353, 0.817635, 0.436863, + 0.921858, 0.821135, 0.443762, + 0.925342, 0.824620, 0.450643, + 0.928815, 0.828096, 0.457507, + 0.932278, 0.831569, 0.464376, + 0.935735, 0.835023, 0.471215, + 0.939177, 0.838471, 0.478042, + 0.942613, 0.841917, 0.484861, + 0.946034, 0.845350, 0.491688, + 0.949452, 0.848781, 0.498492, + 0.952864, 0.852210, 0.505275, + 0.956267, 0.855629, 0.512068, + 0.959662, 0.859041, 0.518860, + 0.963051, 0.862459, 0.525632, + 0.966431, 0.865865, 0.532407, + 0.969807, 0.869272, 0.539168, + 0.973179, 0.872677, 0.545938, + 0.976539, 0.876078, 0.552691, + 0.979899, 0.879477, 0.559448, + 0.983247, 0.882877, 0.566201, + 0.986594, 0.886282, 0.572957, + 0.989930, 0.889679, 0.579707, + 0.993263, 0.893078, 0.586451, + 0.996581, 0.896481, 0.593202, + 0.999903, 0.899882, 0.599947, +}; + +const float ColorMap::m_plasma[m_size] = +{ + 0.0504, 0.0298, 0.5280, + 0.0635, 0.0284, 0.5331, + 0.0754, 0.0272, 0.5380, + 0.0862, 0.0261, 0.5427, + 0.0964, 0.0252, 0.5471, + 0.1060, 0.0243, 0.5514, + 0.1151, 0.0236, 0.5555, + 0.1239, 0.0229, 0.5594, + 0.1324, 0.0223, 0.5633, + 0.1406, 0.0217, 0.5670, + 0.1486, 0.0212, 0.5706, + 0.1564, 0.0207, 0.5741, + 0.1641, 0.0202, 0.5775, + 0.1716, 0.0197, 0.5808, + 0.1789, 0.0193, 0.5841, + 0.1862, 0.0188, 0.5872, + 0.1934, 0.0184, 0.5903, + 0.2004, 0.0179, 0.5934, + 0.2074, 0.0174, 0.5963, + 0.2144, 0.0170, 0.5992, + 0.2212, 0.0165, 0.6021, + 0.2280, 0.0160, 0.6049, + 0.2347, 0.0155, 0.6076, + 0.2414, 0.0150, 0.6103, + 0.2480, 0.0144, 0.6129, + 0.2546, 0.0139, 0.6154, + 0.2612, 0.0133, 0.6179, + 0.2677, 0.0127, 0.6203, + 0.2742, 0.0121, 0.6227, + 0.2806, 0.0115, 0.6250, + 0.2871, 0.0109, 0.6273, + 0.2935, 0.0102, 0.6295, + 0.2999, 0.0096, 0.6316, + 0.3062, 0.0089, 0.6337, + 0.3125, 0.0082, 0.6357, + 0.3189, 0.0076, 0.6376, + 0.3251, 0.0069, 0.6395, + 0.3314, 0.0063, 0.6413, + 0.3377, 0.0056, 0.6430, + 0.3439, 0.0050, 0.6447, + 0.3502, 0.0044, 0.6463, + 0.3564, 0.0038, 0.6478, + 0.3626, 0.0032, 0.6492, + 0.3687, 0.0027, 0.6506, + 0.3749, 0.0022, 0.6519, + 0.3810, 0.0018, 0.6531, + 0.3872, 0.0014, 0.6542, + 0.3933, 0.0011, 0.6552, + 0.3994, 0.0009, 0.6561, + 0.4055, 0.0007, 0.6570, + 0.4116, 0.0006, 0.6577, + 0.4176, 0.0006, 0.6584, + 0.4237, 0.0006, 0.6590, + 0.4297, 0.0008, 0.6594, + 0.4357, 0.0011, 0.6598, + 0.4417, 0.0015, 0.6601, + 0.4477, 0.0021, 0.6602, + 0.4537, 0.0028, 0.6603, + 0.4596, 0.0036, 0.6603, + 0.4656, 0.0045, 0.6601, + 0.4715, 0.0057, 0.6599, + 0.4773, 0.0070, 0.6595, + 0.4832, 0.0085, 0.6591, + 0.4891, 0.0101, 0.6585, + 0.4949, 0.0120, 0.6579, + 0.5007, 0.0141, 0.6571, + 0.5065, 0.0163, 0.6562, + 0.5122, 0.0188, 0.6552, + 0.5179, 0.0216, 0.6541, + 0.5236, 0.0245, 0.6529, + 0.5293, 0.0277, 0.6516, + 0.5350, 0.0312, 0.6502, + 0.5406, 0.0350, 0.6486, + 0.5462, 0.0390, 0.6470, + 0.5517, 0.0431, 0.6453, + 0.5572, 0.0473, 0.6434, + 0.5627, 0.0515, 0.6415, + 0.5682, 0.0558, 0.6395, + 0.5736, 0.0600, 0.6373, + 0.5790, 0.0643, 0.6351, + 0.5844, 0.0686, 0.6328, + 0.5897, 0.0729, 0.6304, + 0.5950, 0.0772, 0.6279, + 0.6003, 0.0815, 0.6253, + 0.6055, 0.0859, 0.6227, + 0.6107, 0.0902, 0.6200, + 0.6158, 0.0946, 0.6171, + 0.6209, 0.0989, 0.6143, + 0.6260, 0.1033, 0.6113, + 0.6310, 0.1077, 0.6083, + 0.6360, 0.1121, 0.6052, + 0.6410, 0.1165, 0.6021, + 0.6459, 0.1209, 0.5989, + 0.6507, 0.1253, 0.5956, + 0.6556, 0.1297, 0.5923, + 0.6604, 0.1341, 0.5890, + 0.6651, 0.1386, 0.5856, + 0.6698, 0.1430, 0.5822, + 0.6745, 0.1474, 0.5787, + 0.6792, 0.1518, 0.5752, + 0.6838, 0.1563, 0.5717, + 0.6883, 0.1607, 0.5681, + 0.6928, 0.1651, 0.5645, + 0.6973, 0.1696, 0.5609, + 0.7018, 0.1740, 0.5573, + 0.7062, 0.1784, 0.5537, + 0.7105, 0.1829, 0.5500, + 0.7149, 0.1873, 0.5463, + 0.7192, 0.1917, 0.5427, + 0.7234, 0.1962, 0.5390, + 0.7277, 0.2006, 0.5353, + 0.7319, 0.2050, 0.5316, + 0.7360, 0.2094, 0.5279, + 0.7401, 0.2139, 0.5242, + 0.7442, 0.2183, 0.5205, + 0.7483, 0.2227, 0.5168, + 0.7523, 0.2271, 0.5131, + 0.7563, 0.2316, 0.5095, + 0.7603, 0.2360, 0.5058, + 0.7642, 0.2404, 0.5021, + 0.7681, 0.2448, 0.4985, + 0.7720, 0.2492, 0.4948, + 0.7758, 0.2537, 0.4912, + 0.7796, 0.2581, 0.4875, + 0.7834, 0.2625, 0.4839, + 0.7871, 0.2669, 0.4803, + 0.7909, 0.2713, 0.4767, + 0.7945, 0.2758, 0.4731, + 0.7982, 0.2802, 0.4695, + 0.8019, 0.2846, 0.4660, + 0.8055, 0.2891, 0.4624, + 0.8091, 0.2935, 0.4589, + 0.8126, 0.2979, 0.4553, + 0.8161, 0.3024, 0.4518, + 0.8197, 0.3068, 0.4483, + 0.8231, 0.3113, 0.4448, + 0.8266, 0.3157, 0.4413, + 0.8300, 0.3202, 0.4378, + 0.8334, 0.3246, 0.4344, + 0.8368, 0.3291, 0.4309, + 0.8402, 0.3336, 0.4275, + 0.8435, 0.3381, 0.4240, + 0.8468, 0.3426, 0.4206, + 0.8501, 0.3470, 0.4172, + 0.8533, 0.3516, 0.4137, + 0.8565, 0.3561, 0.4103, + 0.8598, 0.3606, 0.4069, + 0.8629, 0.3651, 0.4035, + 0.8661, 0.3697, 0.4001, + 0.8692, 0.3742, 0.3967, + 0.8723, 0.3788, 0.3934, + 0.8754, 0.3833, 0.3900, + 0.8784, 0.3879, 0.3866, + 0.8814, 0.3925, 0.3832, + 0.8844, 0.3971, 0.3799, + 0.8874, 0.4018, 0.3765, + 0.8903, 0.4064, 0.3731, + 0.8932, 0.4110, 0.3698, + 0.8961, 0.4157, 0.3664, + 0.8990, 0.4204, 0.3630, + 0.9018, 0.4251, 0.3597, + 0.9046, 0.4298, 0.3563, + 0.9074, 0.4345, 0.3530, + 0.9101, 0.4393, 0.3496, + 0.9128, 0.4440, 0.3463, + 0.9155, 0.4488, 0.3429, + 0.9181, 0.4536, 0.3395, + 0.9207, 0.4584, 0.3362, + 0.9233, 0.4633, 0.3328, + 0.9258, 0.4681, 0.3294, + 0.9283, 0.4730, 0.3261, + 0.9308, 0.4779, 0.3227, + 0.9332, 0.4828, 0.3193, + 0.9356, 0.4877, 0.3160, + 0.9380, 0.4927, 0.3126, + 0.9403, 0.4976, 0.3092, + 0.9426, 0.5026, 0.3058, + 0.9448, 0.5077, 0.3024, + 0.9471, 0.5127, 0.2990, + 0.9492, 0.5178, 0.2957, + 0.9513, 0.5229, 0.2923, + 0.9534, 0.5280, 0.2889, + 0.9555, 0.5331, 0.2855, + 0.9575, 0.5383, 0.2821, + 0.9594, 0.5434, 0.2787, + 0.9613, 0.5486, 0.2753, + 0.9632, 0.5539, 0.2719, + 0.9650, 0.5591, 0.2685, + 0.9668, 0.5644, 0.2651, + 0.9685, 0.5697, 0.2617, + 0.9702, 0.5750, 0.2583, + 0.9718, 0.5804, 0.2549, + 0.9734, 0.5858, 0.2515, + 0.9749, 0.5912, 0.2482, + 0.9764, 0.5966, 0.2448, + 0.9779, 0.6021, 0.2414, + 0.9792, 0.6075, 0.2380, + 0.9806, 0.6130, 0.2346, + 0.9818, 0.6186, 0.2313, + 0.9830, 0.6241, 0.2279, + 0.9842, 0.6297, 0.2246, + 0.9853, 0.6353, 0.2213, + 0.9863, 0.6410, 0.2179, + 0.9873, 0.6466, 0.2146, + 0.9883, 0.6523, 0.2114, + 0.9891, 0.6580, 0.2081, + 0.9899, 0.6638, 0.2049, + 0.9907, 0.6696, 0.2016, + 0.9914, 0.6754, 0.1985, + 0.9920, 0.6812, 0.1953, + 0.9925, 0.6870, 0.1922, + 0.9930, 0.6929, 0.1891, + 0.9935, 0.6988, 0.1860, + 0.9938, 0.7047, 0.1830, + 0.9941, 0.7107, 0.1801, + 0.9943, 0.7167, 0.1772, + 0.9945, 0.7227, 0.1744, + 0.9946, 0.7287, 0.1716, + 0.9946, 0.7348, 0.1689, + 0.9945, 0.7409, 0.1663, + 0.9944, 0.7470, 0.1638, + 0.9941, 0.7531, 0.1614, + 0.9939, 0.7593, 0.1591, + 0.9935, 0.7655, 0.1569, + 0.9930, 0.7717, 0.1548, + 0.9925, 0.7780, 0.1529, + 0.9919, 0.7842, 0.1510, + 0.9912, 0.7905, 0.1494, + 0.9904, 0.7969, 0.1479, + 0.9896, 0.8032, 0.1465, + 0.9886, 0.8096, 0.1454, + 0.9876, 0.8160, 0.1444, + 0.9865, 0.8224, 0.1436, + 0.9853, 0.8288, 0.1429, + 0.9840, 0.8353, 0.1425, + 0.9827, 0.8418, 0.1423, + 0.9812, 0.8483, 0.1423, + 0.9796, 0.8549, 0.1425, + 0.9780, 0.8614, 0.1428, + 0.9763, 0.8680, 0.1434, + 0.9744, 0.8746, 0.1441, + 0.9725, 0.8812, 0.1449, + 0.9705, 0.8879, 0.1459, + 0.9684, 0.8946, 0.1470, + 0.9663, 0.9012, 0.1482, + 0.9640, 0.9080, 0.1494, + 0.9617, 0.9147, 0.1505, + 0.9593, 0.9214, 0.1516, + 0.9568, 0.9282, 0.1524, + 0.9543, 0.9349, 0.1529, + 0.9517, 0.9417, 0.1529, + 0.9492, 0.9484, 0.1522, + 0.9466, 0.9552, 0.1503, + 0.9442, 0.9619, 0.1469, + 0.9419, 0.9686, 0.1410, + 0.9400, 0.9752, 0.1313, +}; + +const float ColorMap::m_rainbow[m_size] = +{ + 0.5000, 0.0000, 1.0000, + 0.4922, 0.0123, 1.0000, + 0.4843, 0.0246, 0.9999, + 0.4765, 0.0370, 0.9998, + 0.4686, 0.0493, 0.9997, + 0.4608, 0.0616, 0.9995, + 0.4529, 0.0739, 0.9993, + 0.4451, 0.0861, 0.9991, + 0.4373, 0.0984, 0.9988, + 0.4294, 0.1107, 0.9985, + 0.4216, 0.1229, 0.9981, + 0.4137, 0.1351, 0.9977, + 0.4059, 0.1473, 0.9973, + 0.3980, 0.1595, 0.9968, + 0.3902, 0.1716, 0.9963, + 0.3824, 0.1837, 0.9957, + 0.3745, 0.1958, 0.9951, + 0.3667, 0.2079, 0.9945, + 0.3588, 0.2199, 0.9939, + 0.3510, 0.2319, 0.9932, + 0.3431, 0.2439, 0.9924, + 0.3353, 0.2558, 0.9916, + 0.3275, 0.2677, 0.9908, + 0.3196, 0.2796, 0.9900, + 0.3118, 0.2914, 0.9891, + 0.3039, 0.3032, 0.9882, + 0.2961, 0.3149, 0.9872, + 0.2882, 0.3265, 0.9862, + 0.2804, 0.3382, 0.9852, + 0.2725, 0.3497, 0.9841, + 0.2647, 0.3612, 0.9830, + 0.2569, 0.3727, 0.9818, + 0.2490, 0.3841, 0.9806, + 0.2412, 0.3955, 0.9794, + 0.2333, 0.4067, 0.9781, + 0.2255, 0.4180, 0.9768, + 0.2176, 0.4291, 0.9755, + 0.2098, 0.4402, 0.9741, + 0.2020, 0.4512, 0.9727, + 0.1941, 0.4622, 0.9713, + 0.1863, 0.4731, 0.9698, + 0.1784, 0.4839, 0.9683, + 0.1706, 0.4947, 0.9667, + 0.1627, 0.5053, 0.9651, + 0.1549, 0.5159, 0.9635, + 0.1471, 0.5264, 0.9618, + 0.1392, 0.5369, 0.9601, + 0.1314, 0.5472, 0.9584, + 0.1235, 0.5575, 0.9566, + 0.1157, 0.5677, 0.9548, + 0.1078, 0.5778, 0.9529, + 0.1000, 0.5878, 0.9511, + 0.0922, 0.5977, 0.9491, + 0.0843, 0.6075, 0.9472, + 0.0765, 0.6173, 0.9452, + 0.0686, 0.6269, 0.9432, + 0.0608, 0.6365, 0.9411, + 0.0529, 0.6459, 0.9390, + 0.0451, 0.6553, 0.9369, + 0.0373, 0.6645, 0.9347, + 0.0294, 0.6737, 0.9325, + 0.0216, 0.6827, 0.9302, + 0.0137, 0.6917, 0.9280, + 0.0059, 0.7005, 0.9256, + 0.0020, 0.7093, 0.9233, + 0.0098, 0.7179, 0.9209, + 0.0176, 0.7264, 0.9185, + 0.0255, 0.7348, 0.9160, + 0.0333, 0.7431, 0.9135, + 0.0412, 0.7513, 0.9110, + 0.0490, 0.7594, 0.9085, + 0.0569, 0.7674, 0.9059, + 0.0647, 0.7752, 0.9032, + 0.0725, 0.7829, 0.9006, + 0.0804, 0.7905, 0.8979, + 0.0882, 0.7980, 0.8952, + 0.0961, 0.8054, 0.8924, + 0.1039, 0.8126, 0.8896, + 0.1118, 0.8197, 0.8868, + 0.1196, 0.8267, 0.8839, + 0.1275, 0.8336, 0.8810, + 0.1353, 0.8403, 0.8781, + 0.1431, 0.8470, 0.8751, + 0.1510, 0.8534, 0.8721, + 0.1588, 0.8598, 0.8691, + 0.1667, 0.8660, 0.8660, + 0.1745, 0.8721, 0.8629, + 0.1824, 0.8781, 0.8598, + 0.1902, 0.8839, 0.8566, + 0.1980, 0.8896, 0.8534, + 0.2059, 0.8952, 0.8502, + 0.2137, 0.9006, 0.8470, + 0.2216, 0.9059, 0.8437, + 0.2294, 0.9110, 0.8403, + 0.2373, 0.9160, 0.8370, + 0.2451, 0.9209, 0.8336, + 0.2529, 0.9256, 0.8302, + 0.2608, 0.9302, 0.8267, + 0.2686, 0.9347, 0.8233, + 0.2765, 0.9390, 0.8197, + 0.2843, 0.9432, 0.8162, + 0.2922, 0.9472, 0.8126, + 0.3000, 0.9511, 0.8090, + 0.3078, 0.9548, 0.8054, + 0.3157, 0.9584, 0.8017, + 0.3235, 0.9618, 0.7980, + 0.3314, 0.9651, 0.7943, + 0.3392, 0.9683, 0.7905, + 0.3471, 0.9713, 0.7867, + 0.3549, 0.9741, 0.7829, + 0.3627, 0.9768, 0.7791, + 0.3706, 0.9794, 0.7752, + 0.3784, 0.9818, 0.7713, + 0.3863, 0.9841, 0.7674, + 0.3941, 0.9862, 0.7634, + 0.4020, 0.9882, 0.7594, + 0.4098, 0.9900, 0.7554, + 0.4176, 0.9916, 0.7513, + 0.4255, 0.9932, 0.7473, + 0.4333, 0.9945, 0.7431, + 0.4412, 0.9957, 0.7390, + 0.4490, 0.9968, 0.7348, + 0.4569, 0.9977, 0.7307, + 0.4647, 0.9985, 0.7264, + 0.4725, 0.9991, 0.7222, + 0.4804, 0.9995, 0.7179, + 0.4882, 0.9998, 0.7136, + 0.4961, 1.0000, 0.7093, + 0.5039, 1.0000, 0.7049, + 0.5118, 0.9998, 0.7005, + 0.5196, 0.9995, 0.6961, + 0.5275, 0.9991, 0.6917, + 0.5353, 0.9985, 0.6872, + 0.5431, 0.9977, 0.6827, + 0.5510, 0.9968, 0.6782, + 0.5588, 0.9957, 0.6737, + 0.5667, 0.9945, 0.6691, + 0.5745, 0.9932, 0.6645, + 0.5824, 0.9916, 0.6599, + 0.5902, 0.9900, 0.6553, + 0.5980, 0.9882, 0.6506, + 0.6059, 0.9862, 0.6459, + 0.6137, 0.9841, 0.6412, + 0.6216, 0.9818, 0.6365, + 0.6294, 0.9794, 0.6317, + 0.6373, 0.9768, 0.6269, + 0.6451, 0.9741, 0.6221, + 0.6529, 0.9713, 0.6173, + 0.6608, 0.9683, 0.6124, + 0.6686, 0.9651, 0.6075, + 0.6765, 0.9618, 0.6026, + 0.6843, 0.9584, 0.5977, + 0.6922, 0.9548, 0.5928, + 0.7000, 0.9511, 0.5878, + 0.7078, 0.9472, 0.5828, + 0.7157, 0.9432, 0.5778, + 0.7235, 0.9390, 0.5727, + 0.7314, 0.9347, 0.5677, + 0.7392, 0.9302, 0.5626, + 0.7471, 0.9256, 0.5575, + 0.7549, 0.9209, 0.5524, + 0.7627, 0.9160, 0.5472, + 0.7706, 0.9110, 0.5421, + 0.7784, 0.9059, 0.5369, + 0.7863, 0.9006, 0.5317, + 0.7941, 0.8952, 0.5264, + 0.8020, 0.8896, 0.5212, + 0.8098, 0.8839, 0.5159, + 0.8176, 0.8781, 0.5106, + 0.8255, 0.8721, 0.5053, + 0.8333, 0.8660, 0.5000, + 0.8412, 0.8598, 0.4947, + 0.8490, 0.8534, 0.4893, + 0.8569, 0.8470, 0.4839, + 0.8647, 0.8403, 0.4785, + 0.8725, 0.8336, 0.4731, + 0.8804, 0.8267, 0.4677, + 0.8882, 0.8197, 0.4622, + 0.8961, 0.8126, 0.4567, + 0.9039, 0.8054, 0.4512, + 0.9118, 0.7980, 0.4457, + 0.9196, 0.7905, 0.4402, + 0.9275, 0.7829, 0.4347, + 0.9353, 0.7752, 0.4291, + 0.9431, 0.7674, 0.4235, + 0.9510, 0.7594, 0.4180, + 0.9588, 0.7513, 0.4124, + 0.9667, 0.7431, 0.4067, + 0.9745, 0.7348, 0.4011, + 0.9824, 0.7264, 0.3955, + 0.9902, 0.7179, 0.3898, + 0.9980, 0.7093, 0.3841, + 1.0000, 0.7005, 0.3784, + 1.0000, 0.6917, 0.3727, + 1.0000, 0.6827, 0.3670, + 1.0000, 0.6737, 0.3612, + 1.0000, 0.6645, 0.3555, + 1.0000, 0.6553, 0.3497, + 1.0000, 0.6459, 0.3439, + 1.0000, 0.6365, 0.3382, + 1.0000, 0.6269, 0.3324, + 1.0000, 0.6173, 0.3265, + 1.0000, 0.6075, 0.3207, + 1.0000, 0.5977, 0.3149, + 1.0000, 0.5878, 0.3090, + 1.0000, 0.5778, 0.3032, + 1.0000, 0.5677, 0.2973, + 1.0000, 0.5575, 0.2914, + 1.0000, 0.5472, 0.2855, + 1.0000, 0.5369, 0.2796, + 1.0000, 0.5264, 0.2737, + 1.0000, 0.5159, 0.2677, + 1.0000, 0.5053, 0.2618, + 1.0000, 0.4947, 0.2558, + 1.0000, 0.4839, 0.2499, + 1.0000, 0.4731, 0.2439, + 1.0000, 0.4622, 0.2379, + 1.0000, 0.4512, 0.2319, + 1.0000, 0.4402, 0.2260, + 1.0000, 0.4291, 0.2199, + 1.0000, 0.4180, 0.2139, + 1.0000, 0.4067, 0.2079, + 1.0000, 0.3955, 0.2019, + 1.0000, 0.3841, 0.1958, + 1.0000, 0.3727, 0.1898, + 1.0000, 0.3612, 0.1837, + 1.0000, 0.3497, 0.1777, + 1.0000, 0.3382, 0.1716, + 1.0000, 0.3265, 0.1656, + 1.0000, 0.3149, 0.1595, + 1.0000, 0.3032, 0.1534, + 1.0000, 0.2914, 0.1473, + 1.0000, 0.2796, 0.1412, + 1.0000, 0.2677, 0.1351, + 1.0000, 0.2558, 0.1290, + 1.0000, 0.2439, 0.1229, + 1.0000, 0.2319, 0.1168, + 1.0000, 0.2199, 0.1107, + 1.0000, 0.2079, 0.1045, + 1.0000, 0.1958, 0.0984, + 1.0000, 0.1837, 0.0923, + 1.0000, 0.1716, 0.0861, + 1.0000, 0.1595, 0.0800, + 1.0000, 0.1473, 0.0739, + 1.0000, 0.1351, 0.0677, + 1.0000, 0.1229, 0.0616, + 1.0000, 0.1107, 0.0554, + 1.0000, 0.0984, 0.0493, + 1.0000, 0.0861, 0.0431, + 1.0000, 0.0739, 0.0370, + 1.0000, 0.0616, 0.0308, + 1.0000, 0.0493, 0.0246, + 1.0000, 0.0370, 0.0185, + 1.0000, 0.0246, 0.0123, + 1.0000, 0.0123, 0.0062, + 1.0000, 0.0000, 0.0000, +}; + +const float ColorMap::m_prism[m_size] = +{ + 1.0000, 0.0000, 0.0000, + 1.0000, 0.0000, 0.0000, + 1.0000, 0.1296, 0.0000, + 1.0000, 0.3203, 0.0000, + 1.0000, 0.5116, 0.0000, + 1.0000, 0.6909, 0.0000, + 1.0000, 0.8464, 0.0000, + 1.0000, 0.9679, 0.0000, + 0.8890, 1.0000, 0.0000, + 0.6991, 1.0000, 0.0000, + 0.5073, 1.0000, 0.0000, + 0.3262, 0.9966, 0.0000, + 0.1678, 0.8870, 0.0000, + 0.0425, 0.7408, 0.2247, + 0.0000, 0.5675, 0.4915, + 0.0000, 0.3785, 0.7259, + 0.0000, 0.1863, 0.9124, + 0.0000, 0.0036, 1.0000, + 0.1001, 0.0000, 1.0000, + 0.2431, 0.0000, 1.0000, + 0.4142, 0.0000, 0.9965, + 0.6022, 0.0000, 0.8450, + 0.7946, 0.0000, 0.6378, + 0.9788, 0.0000, 0.3885, + 1.0000, 0.0000, 0.1136, + 1.0000, 0.0000, 0.0000, + 1.0000, 0.0561, 0.0000, + 1.0000, 0.2429, 0.0000, + 1.0000, 0.4354, 0.0000, + 1.0000, 0.6211, 0.0000, + 1.0000, 0.7875, 0.0000, + 1.0000, 0.9237, 0.0000, + 0.9619, 1.0000, 0.0000, + 0.7764, 1.0000, 0.0000, + 0.5838, 1.0000, 0.0000, + 0.3969, 1.0000, 0.0000, + 0.2280, 0.9359, 0.0000, + 0.0883, 0.8034, 0.1123, + 0.0000, 0.6397, 0.3872, + 0.0000, 0.4555, 0.6367, + 0.0000, 0.2631, 0.8441, + 0.0000, 0.0751, 0.9959, + 0.0528, 0.0000, 1.0000, + 0.1817, 0.0000, 1.0000, + 0.3427, 0.0000, 1.0000, + 0.5254, 0.0000, 0.9132, + 0.7176, 0.0000, 0.7269, + 0.9066, 0.0000, 0.4927, + 1.0000, 0.0000, 0.2261, + 1.0000, 0.0000, 0.0000, + 1.0000, 0.0000, 0.0000, + 1.0000, 0.1664, 0.0000, + 1.0000, 0.3582, 0.0000, + 1.0000, 0.5481, 0.0000, + 1.0000, 0.7236, 0.0000, + 1.0000, 0.8732, 0.0000, + 1.0000, 0.9870, 0.0000, + 0.8525, 1.0000, 0.0000, + 0.6612, 1.0000, 0.0000, + 0.4705, 1.0000, 0.0000, + 0.2930, 0.9784, 0.0000, + 0.1403, 0.8610, 0.0000, + 0.0226, 0.7086, 0.2788, + 0.0000, 0.5312, 0.5406, + 0.0000, 0.3406, 0.7667, + 0.0000, 0.1493, 0.9423, + 0.0121, 0.0000, 1.0000, + 0.1255, 0.0000, 1.0000, + 0.2748, 0.0000, 1.0000, + 0.4501, 0.0000, 0.9717, + 0.6400, 0.0000, 0.8083, + 0.8318, 0.0000, 0.5917, + 1.0000, 0.0000, 0.3360, + 1.0000, 0.0000, 0.0582, + 1.0000, 0.0000, 0.0000, + 1.0000, 0.0917, 0.0000, + 1.0000, 0.2806, 0.0000, + 1.0000, 0.4728, 0.0000, + 1.0000, 0.6556, 0.0000, + 1.0000, 0.8169, 0.0000, + 1.0000, 0.9461, 0.0000, + 0.9267, 1.0000, 0.0000, + 0.7387, 1.0000, 0.0000, + 0.5463, 1.0000, 0.0000, + 0.3620, 1.0000, 0.0000, + 0.1980, 0.9129, 0.0000, + 0.0651, 0.7735, 0.1674, + 0.0000, 0.6048, 0.4387, + 0.0000, 0.4180, 0.6811, + 0.0000, 0.2255, 0.8786, + 0.0000, 0.0398, 1.0000, + 0.0751, 0.0000, 1.0000, + 0.2111, 0.0000, 1.0000, + 0.3772, 0.0000, 1.0000, + 0.5627, 0.0000, 0.8811, + 0.7553, 0.0000, 0.6843, + 0.9422, 0.0000, 0.4425, + 1.0000, 0.0000, 0.1714, + 1.0000, 0.0000, 0.0000, + 1.0000, 0.0195, 0.0000, + 1.0000, 0.2036, 0.0000, + 1.0000, 0.3960, 0.0000, + 1.0000, 0.5841, 0.0000, + 1.0000, 0.7554, 0.0000, + 1.0000, 0.8987, 0.0000, + 0.9981, 1.0000, 0.0000, + 0.8155, 1.0000, 0.0000, + 0.6234, 1.0000, 0.0000, + 0.4343, 1.0000, 0.0000, + 0.2607, 0.9585, 0.0000, + 0.1142, 0.8336, 0.0542, + 0.0043, 0.6754, 0.3322, + 0.0000, 0.4945, 0.5883, + 0.0000, 0.3027, 0.8056, + 0.0000, 0.1128, 0.9698, + 0.0311, 0.0000, 1.0000, + 0.1522, 0.0000, 1.0000, + 0.3075, 0.0000, 1.0000, + 0.4866, 0.0000, 0.9444, + 0.6779, 0.0000, 0.7696, + 0.8686, 0.0000, 0.5441, + 1.0000, 0.0000, 0.2827, + 1.0000, 0.0000, 0.0027, + 1.0000, 0.0000, 0.0000, + 1.0000, 0.1279, 0.0000, + 1.0000, 0.3185, 0.0000, + 1.0000, 0.5098, 0.0000, + 1.0000, 0.6893, 0.0000, + 1.0000, 0.8451, 0.0000, + 1.0000, 0.9669, 0.0000, + 0.8908, 1.0000, 0.0000, + 0.7009, 1.0000, 0.0000, + 0.5091, 1.0000, 0.0000, + 0.3279, 0.9974, 0.0000, + 0.1692, 0.8883, 0.0000, + 0.0435, 0.7423, 0.2221, + 0.0000, 0.5692, 0.4891, + 0.0000, 0.3803, 0.7239, + 0.0000, 0.1881, 0.9109, + 0.0000, 0.0052, 1.0000, + 0.0989, 0.0000, 1.0000, + 0.2416, 0.0000, 1.0000, + 0.4125, 0.0000, 0.9976, + 0.6003, 0.0000, 0.8467, + 0.7928, 0.0000, 0.6400, + 0.9772, 0.0000, 0.3910, + 1.0000, 0.0000, 0.1163, + 1.0000, 0.0000, 0.0000, + 1.0000, 0.0543, 0.0000, + 1.0000, 0.2410, 0.0000, + 1.0000, 0.4336, 0.0000, + 1.0000, 0.6194, 0.0000, + 1.0000, 0.7860, 0.0000, + 1.0000, 0.9226, 0.0000, + 0.9636, 1.0000, 0.0000, + 0.7782, 1.0000, 0.0000, + 0.5856, 1.0000, 0.0000, + 0.3986, 1.0000, 0.0000, + 0.2295, 0.9370, 0.0000, + 0.0895, 0.8049, 0.1096, + 0.0000, 0.6414, 0.3847, + 0.0000, 0.4574, 0.6344, + 0.0000, 0.2649, 0.8424, + 0.0000, 0.0768, 0.9947, + 0.0518, 0.0000, 1.0000, + 0.1803, 0.0000, 1.0000, + 0.3411, 0.0000, 1.0000, + 0.5236, 0.0000, 0.9147, + 0.7157, 0.0000, 0.7290, + 0.9048, 0.0000, 0.4952, + 1.0000, 0.0000, 0.2287, + 1.0000, 0.0000, 0.0000, + 1.0000, 0.0000, 0.0000, + 1.0000, 0.1646, 0.0000, + 1.0000, 0.3563, 0.0000, + 1.0000, 0.5463, 0.0000, + 1.0000, 0.7221, 0.0000, + 1.0000, 0.8720, 0.0000, + 1.0000, 0.9861, 0.0000, + 0.8543, 1.0000, 0.0000, + 0.6631, 1.0000, 0.0000, + 0.4723, 1.0000, 0.0000, + 0.2946, 0.9793, 0.0000, + 0.1416, 0.8623, 0.0000, + 0.0235, 0.7102, 0.2762, + 0.0000, 0.5330, 0.5382, + 0.0000, 0.3425, 0.7648, + 0.0000, 0.1511, 0.9409, + 0.0112, 0.0000, 1.0000, + 0.1242, 0.0000, 1.0000, + 0.2732, 0.0000, 1.0000, + 0.4484, 0.0000, 0.9729, + 0.6381, 0.0000, 0.8102, + 0.8300, 0.0000, 0.5940, + 1.0000, 0.0000, 0.3386, + 1.0000, 0.0000, 0.0610, + 1.0000, 0.0000, 0.0000, + 1.0000, 0.0899, 0.0000, + 1.0000, 0.2788, 0.0000, + 1.0000, 0.4710, 0.0000, + 1.0000, 0.6539, 0.0000, + 1.0000, 0.8155, 0.0000, + 1.0000, 0.9451, 0.0000, + 0.9284, 1.0000, 0.0000, + 0.7406, 1.0000, 0.0000, + 0.5481, 1.0000, 0.0000, + 0.3637, 1.0000, 0.0000, + 0.1994, 0.9140, 0.0000, + 0.0662, 0.7749, 0.1647, + 0.0000, 0.6065, 0.4362, + 0.0000, 0.4199, 0.6790, + 0.0000, 0.2273, 0.8770, + 0.0000, 0.0415, 1.0000, + 0.0740, 0.0000, 1.0000, + 0.2096, 0.0000, 1.0000, + 0.3755, 0.0000, 1.0000, + 0.5609, 0.0000, 0.8827, + 0.7534, 0.0000, 0.6864, + 0.9405, 0.0000, 0.4449, + 1.0000, 0.0000, 0.1741, + 1.0000, 0.0000, 0.0000, + 1.0000, 0.0178, 0.0000, + 1.0000, 0.2017, 0.0000, + 1.0000, 0.3941, 0.0000, + 1.0000, 0.5823, 0.0000, + 1.0000, 0.7539, 0.0000, + 1.0000, 0.8974, 0.0000, + 0.9997, 1.0000, 0.0000, + 0.8173, 1.0000, 0.0000, + 0.6252, 1.0000, 0.0000, + 0.4360, 1.0000, 0.0000, + 0.2623, 0.9595, 0.0000, + 0.1154, 0.8349, 0.0515, + 0.0051, 0.6771, 0.3296, + 0.0000, 0.4963, 0.5860, + 0.0000, 0.3046, 0.8037, + 0.0000, 0.1146, 0.9685, + 0.0302, 0.0000, 1.0000, + 0.1509, 0.0000, 1.0000, + 0.3059, 0.0000, 1.0000, + 0.4848, 0.0000, 0.9458, + 0.6760, 0.0000, 0.7716, + 0.8668, 0.0000, 0.5465, + 1.0000, 0.0000, 0.2854, + 1.0000, 0.0000, 0.0054, + 1.0000, 0.0000, 0.0000, + 1.0000, 0.1261, 0.0000, + 1.0000, 0.3166, 0.0000, + 1.0000, 0.5080, 0.0000, + 1.0000, 0.6877, 0.0000, + 1.0000, 0.8437, 0.0000, + 1.0000, 0.9660, 0.0000, + 0.8925, 1.0000, 0.0000, + 0.7028, 1.0000, 0.0000, + 0.5109, 1.0000, 0.0000, + 0.3295, 0.9983, 0.0000, +}; + +const float ColorMap::m_viridis[m_size] = +{ + 0.2670, 0.0049, 0.3294, + 0.2685, 0.0096, 0.3354, + 0.2699, 0.0146, 0.3414, + 0.2713, 0.0199, 0.3473, + 0.2726, 0.0256, 0.3531, + 0.2738, 0.0315, 0.3589, + 0.2750, 0.0378, 0.3645, + 0.2760, 0.0442, 0.3702, + 0.2770, 0.0503, 0.3757, + 0.2779, 0.0563, 0.3812, + 0.2788, 0.0621, 0.3866, + 0.2796, 0.0678, 0.3919, + 0.2803, 0.0734, 0.3972, + 0.2809, 0.0789, 0.4023, + 0.2814, 0.0843, 0.4074, + 0.2819, 0.0897, 0.4124, + 0.2823, 0.0950, 0.4173, + 0.2827, 0.1002, 0.4222, + 0.2829, 0.1054, 0.4269, + 0.2831, 0.1106, 0.4316, + 0.2832, 0.1157, 0.4361, + 0.2832, 0.1208, 0.4406, + 0.2832, 0.1258, 0.4450, + 0.2831, 0.1309, 0.4492, + 0.2829, 0.1359, 0.4534, + 0.2826, 0.1409, 0.4575, + 0.2823, 0.1459, 0.4615, + 0.2819, 0.1509, 0.4654, + 0.2814, 0.1558, 0.4692, + 0.2809, 0.1608, 0.4729, + 0.2803, 0.1657, 0.4765, + 0.2796, 0.1706, 0.4800, + 0.2788, 0.1755, 0.4834, + 0.2780, 0.1804, 0.4867, + 0.2771, 0.1852, 0.4899, + 0.2762, 0.1901, 0.4930, + 0.2752, 0.1949, 0.4960, + 0.2741, 0.1997, 0.4989, + 0.2730, 0.2045, 0.5017, + 0.2718, 0.2093, 0.5044, + 0.2706, 0.2141, 0.5071, + 0.2693, 0.2188, 0.5096, + 0.2680, 0.2235, 0.5120, + 0.2666, 0.2283, 0.5143, + 0.2651, 0.2330, 0.5166, + 0.2637, 0.2376, 0.5188, + 0.2621, 0.2423, 0.5208, + 0.2606, 0.2469, 0.5228, + 0.2590, 0.2515, 0.5247, + 0.2573, 0.2561, 0.5266, + 0.2556, 0.2607, 0.5283, + 0.2539, 0.2653, 0.5300, + 0.2522, 0.2698, 0.5316, + 0.2504, 0.2743, 0.5331, + 0.2486, 0.2788, 0.5346, + 0.2468, 0.2832, 0.5359, + 0.2450, 0.2877, 0.5373, + 0.2431, 0.2921, 0.5385, + 0.2412, 0.2965, 0.5397, + 0.2393, 0.3009, 0.5408, + 0.2374, 0.3052, 0.5419, + 0.2355, 0.3095, 0.5429, + 0.2336, 0.3138, 0.5439, + 0.2317, 0.3181, 0.5448, + 0.2297, 0.3224, 0.5457, + 0.2278, 0.3266, 0.5465, + 0.2259, 0.3308, 0.5473, + 0.2239, 0.3350, 0.5481, + 0.2220, 0.3392, 0.5488, + 0.2201, 0.3433, 0.5494, + 0.2181, 0.3474, 0.5500, + 0.2162, 0.3515, 0.5506, + 0.2143, 0.3556, 0.5512, + 0.2124, 0.3597, 0.5517, + 0.2105, 0.3637, 0.5522, + 0.2086, 0.3678, 0.5527, + 0.2068, 0.3718, 0.5531, + 0.2049, 0.3757, 0.5535, + 0.2031, 0.3797, 0.5539, + 0.2012, 0.3837, 0.5543, + 0.1994, 0.3876, 0.5546, + 0.1976, 0.3915, 0.5550, + 0.1959, 0.3954, 0.5553, + 0.1941, 0.3993, 0.5556, + 0.1924, 0.4032, 0.5558, + 0.1906, 0.4071, 0.5561, + 0.1889, 0.4109, 0.5563, + 0.1872, 0.4147, 0.5565, + 0.1856, 0.4186, 0.5568, + 0.1839, 0.4224, 0.5569, + 0.1823, 0.4262, 0.5571, + 0.1806, 0.4300, 0.5573, + 0.1790, 0.4338, 0.5574, + 0.1774, 0.4375, 0.5576, + 0.1758, 0.4413, 0.5577, + 0.1743, 0.4450, 0.5578, + 0.1727, 0.4488, 0.5579, + 0.1712, 0.4525, 0.5580, + 0.1696, 0.4563, 0.5580, + 0.1681, 0.4600, 0.5581, + 0.1666, 0.4637, 0.5581, + 0.1651, 0.4674, 0.5581, + 0.1636, 0.4711, 0.5581, + 0.1621, 0.4748, 0.5581, + 0.1607, 0.4785, 0.5581, + 0.1592, 0.4822, 0.5581, + 0.1577, 0.4859, 0.5580, + 0.1563, 0.4896, 0.5579, + 0.1548, 0.4933, 0.5578, + 0.1534, 0.4970, 0.5577, + 0.1519, 0.5007, 0.5576, + 0.1505, 0.5044, 0.5574, + 0.1490, 0.5081, 0.5573, + 0.1476, 0.5117, 0.5570, + 0.1462, 0.5154, 0.5568, + 0.1448, 0.5191, 0.5566, + 0.1433, 0.5228, 0.5563, + 0.1419, 0.5265, 0.5560, + 0.1405, 0.5301, 0.5557, + 0.1391, 0.5338, 0.5553, + 0.1378, 0.5375, 0.5549, + 0.1364, 0.5412, 0.5545, + 0.1351, 0.5449, 0.5540, + 0.1337, 0.5485, 0.5535, + 0.1324, 0.5522, 0.5530, + 0.1312, 0.5559, 0.5525, + 0.1299, 0.5596, 0.5519, + 0.1287, 0.5633, 0.5512, + 0.1276, 0.5669, 0.5506, + 0.1265, 0.5706, 0.5498, + 0.1254, 0.5743, 0.5491, + 0.1244, 0.5780, 0.5483, + 0.1235, 0.5817, 0.5474, + 0.1226, 0.5854, 0.5466, + 0.1218, 0.5891, 0.5456, + 0.1211, 0.5927, 0.5446, + 0.1206, 0.5964, 0.5436, + 0.1201, 0.6001, 0.5425, + 0.1197, 0.6038, 0.5414, + 0.1195, 0.6075, 0.5402, + 0.1194, 0.6111, 0.5390, + 0.1195, 0.6148, 0.5377, + 0.1197, 0.6185, 0.5363, + 0.1201, 0.6222, 0.5349, + 0.1206, 0.6258, 0.5335, + 0.1214, 0.6295, 0.5320, + 0.1223, 0.6332, 0.5304, + 0.1234, 0.6368, 0.5288, + 0.1248, 0.6405, 0.5271, + 0.1263, 0.6441, 0.5253, + 0.1281, 0.6477, 0.5235, + 0.1301, 0.6514, 0.5216, + 0.1323, 0.6550, 0.5197, + 0.1347, 0.6586, 0.5176, + 0.1373, 0.6623, 0.5156, + 0.1402, 0.6659, 0.5134, + 0.1433, 0.6695, 0.5112, + 0.1466, 0.6731, 0.5089, + 0.1501, 0.6766, 0.5066, + 0.1539, 0.6802, 0.5042, + 0.1579, 0.6838, 0.5017, + 0.1620, 0.6873, 0.4991, + 0.1664, 0.6909, 0.4965, + 0.1709, 0.6944, 0.4938, + 0.1757, 0.6979, 0.4910, + 0.1807, 0.7014, 0.4882, + 0.1858, 0.7049, 0.4853, + 0.1911, 0.7084, 0.4823, + 0.1966, 0.7118, 0.4792, + 0.2022, 0.7153, 0.4761, + 0.2080, 0.7187, 0.4729, + 0.2140, 0.7221, 0.4696, + 0.2201, 0.7255, 0.4662, + 0.2264, 0.7289, 0.4628, + 0.2328, 0.7322, 0.4593, + 0.2394, 0.7356, 0.4557, + 0.2461, 0.7389, 0.4520, + 0.2529, 0.7422, 0.4483, + 0.2599, 0.7455, 0.4445, + 0.2669, 0.7488, 0.4406, + 0.2741, 0.7520, 0.4366, + 0.2815, 0.7552, 0.4326, + 0.2889, 0.7584, 0.4284, + 0.2965, 0.7616, 0.4242, + 0.3041, 0.7647, 0.4199, + 0.3119, 0.7678, 0.4156, + 0.3198, 0.7709, 0.4112, + 0.3278, 0.7740, 0.4066, + 0.3359, 0.7770, 0.4020, + 0.3441, 0.7800, 0.3974, + 0.3524, 0.7830, 0.3926, + 0.3607, 0.7860, 0.3878, + 0.3692, 0.7889, 0.3829, + 0.3778, 0.7918, 0.3779, + 0.3864, 0.7946, 0.3729, + 0.3952, 0.7975, 0.3678, + 0.4040, 0.8003, 0.3626, + 0.4129, 0.8030, 0.3573, + 0.4219, 0.8058, 0.3519, + 0.4310, 0.8085, 0.3465, + 0.4401, 0.8111, 0.3410, + 0.4494, 0.8138, 0.3354, + 0.4587, 0.8164, 0.3297, + 0.4681, 0.8189, 0.3240, + 0.4775, 0.8214, 0.3182, + 0.4870, 0.8239, 0.3123, + 0.4966, 0.8264, 0.3064, + 0.5063, 0.8288, 0.3004, + 0.5160, 0.8312, 0.2943, + 0.5258, 0.8335, 0.2881, + 0.5356, 0.8358, 0.2819, + 0.5455, 0.8380, 0.2756, + 0.5555, 0.8403, 0.2693, + 0.5655, 0.8424, 0.2629, + 0.5756, 0.8446, 0.2564, + 0.5857, 0.8467, 0.2499, + 0.5958, 0.8487, 0.2433, + 0.6060, 0.8507, 0.2367, + 0.6163, 0.8527, 0.2301, + 0.6266, 0.8546, 0.2234, + 0.6369, 0.8565, 0.2166, + 0.6473, 0.8584, 0.2099, + 0.6576, 0.8602, 0.2031, + 0.6681, 0.8620, 0.1963, + 0.6785, 0.8637, 0.1895, + 0.6889, 0.8654, 0.1827, + 0.6994, 0.8671, 0.1760, + 0.7099, 0.8688, 0.1693, + 0.7204, 0.8703, 0.1626, + 0.7309, 0.8719, 0.1560, + 0.7414, 0.8734, 0.1496, + 0.7519, 0.8750, 0.1432, + 0.7624, 0.8764, 0.1371, + 0.7729, 0.8779, 0.1311, + 0.7833, 0.8793, 0.1254, + 0.7938, 0.8807, 0.1200, + 0.8042, 0.8820, 0.1150, + 0.8146, 0.8834, 0.1103, + 0.8249, 0.8847, 0.1062, + 0.8353, 0.8860, 0.1026, + 0.8456, 0.8873, 0.0997, + 0.8558, 0.8886, 0.0975, + 0.8660, 0.8899, 0.0960, + 0.8762, 0.8911, 0.0953, + 0.8863, 0.8924, 0.0954, + 0.8963, 0.8936, 0.0963, + 0.9063, 0.8949, 0.0981, + 0.9162, 0.8961, 0.1007, + 0.9261, 0.8973, 0.1041, + 0.9359, 0.8986, 0.1081, + 0.9456, 0.8998, 0.1128, + 0.9553, 0.9011, 0.1181, + 0.9649, 0.9023, 0.1239, + 0.9744, 0.9036, 0.1302, + 0.9839, 0.9049, 0.1369, + 0.9932, 0.9062, 0.1439, +}; diff --git a/sdrbase/util/colormap.h b/sdrbase/util/colormap.h new file mode 100644 index 000000000..7edb05d41 --- /dev/null +++ b/sdrbase/util/colormap.h @@ -0,0 +1,62 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2022 Jon Beniston, M7RCE // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_COLORMAP_H +#define INCLUDE_COLORMAP_H + +#include "export.h" + +#include + +// 256-entry floating point RGB color maps. +// "Angel" is SDRangel's waterfall colormap +// Some common maps from matplotlib +// Scientific colour maps from: +// https://www.nature.com/articles/s41467-020-19160-7 +// https://zenodo.org/record/5501399#.YqhaAu7MLAQ +class SDRBASE_API ColorMap +{ +public: + static QStringList getColorMapNames(); + static const float *getColorMap(const QString &name); + static constexpr int m_size = 256*3; + +private: + static QHash m_colorMaps; + static const float m_angel[m_size]; + static const float m_jet[m_size]; + static const float m_turbo[m_size]; + static const float m_parula[m_size]; + static const float m_hot[m_size]; + static const float m_cool[m_size]; + static const float m_batlow[m_size]; + static const float m_hawaii[m_size]; + static const float m_acton[m_size]; + static const float m_imola[m_size]; + static const float m_tokyo[m_size]; + static const float m_lapaz[m_size]; + static const float m_buda[m_size]; + static const float m_devon[m_size]; + static const float m_lajolla[m_size]; + static const float m_bamako[m_size]; + static const float m_plasma[m_size]; + static const float m_rainbow[m_size]; + static const float m_prism[m_size]; + static const float m_viridis[m_size]; +}; + +#endif diff --git a/sdrgui/CMakeLists.txt b/sdrgui/CMakeLists.txt index 5f6d97ffa..7594bb0d3 100644 --- a/sdrgui/CMakeLists.txt +++ b/sdrgui/CMakeLists.txt @@ -45,10 +45,12 @@ set(sdrgui_SOURCES gui/glscopegui.cpp gui/glshadercolors.cpp gui/glshadersimple.cpp + gui/glshaderspectrogram.cpp gui/glshadertextured.cpp gui/glshadertvarray.cpp gui/glspectrum.cpp gui/glspectrumgui.cpp + gui/graphicsdialog.cpp gui/graphicsviewzoom.cpp gui/httpdownloadmanagergui.cpp gui/indicator.cpp @@ -144,10 +146,12 @@ set(sdrgui_HEADERS gui/glscopegui.h gui/glshadercolors.h gui/glshadersimple.h + gui/glshaderspectrogram.h gui/glshadertvarray.h gui/glshadertextured.h gui/glspectrum.h gui/glspectrumgui.h + gui/graphicsdialog.h gui/graphicsviewzoom.h gui/httpdownloadmanagergui.h gui/indicator.h @@ -224,6 +228,7 @@ set(sdrgui_FORMS gui/fftwisdomdialog.ui gui/glscopegui.ui gui/glspectrumgui.ui + gui/graphicsdialog.ui gui/pluginsdialog.ui gui/audiodialog.ui gui/audioselectdialog.ui diff --git a/sdrgui/gui/glshadersimple.cpp b/sdrgui/gui/glshadersimple.cpp index 29f1fcf74..a5c425c24 100644 --- a/sdrgui/gui/glshadersimple.cpp +++ b/sdrgui/gui/glshadersimple.cpp @@ -60,32 +60,32 @@ void GLShaderSimple::initializeGL() m_program->release(); } -void GLShaderSimple::drawPoints(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices) +void GLShaderSimple::drawPoints(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents) { - draw(GL_POINTS, transformMatrix, color, vertices, nbVertices); + draw(GL_POINTS, transformMatrix, color, vertices, nbVertices, nbComponents); } -void GLShaderSimple::drawPolyline(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices) +void GLShaderSimple::drawPolyline(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents) { - draw(GL_LINE_STRIP, transformMatrix, color, vertices, nbVertices); + draw(GL_LINE_STRIP, transformMatrix, color, vertices, nbVertices, nbComponents); } -void GLShaderSimple::drawSegments(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices) +void GLShaderSimple::drawSegments(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents) { - draw(GL_LINES, transformMatrix, color, vertices, nbVertices); + draw(GL_LINES, transformMatrix, color, vertices, nbVertices, nbComponents); } -void GLShaderSimple::drawContour(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices) +void GLShaderSimple::drawContour(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents) { - draw(GL_LINE_LOOP, transformMatrix, color, vertices, nbVertices); + draw(GL_LINE_LOOP, transformMatrix, color, vertices, nbVertices, nbComponents); } -void GLShaderSimple::drawSurface(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices) +void GLShaderSimple::drawSurface(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents) { - draw(GL_TRIANGLE_FAN, transformMatrix, color, vertices, nbVertices); + draw(GL_TRIANGLE_FAN, transformMatrix, color, vertices, nbVertices, nbComponents); } -void GLShaderSimple::draw(unsigned int mode, const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices) +void GLShaderSimple::draw(unsigned int mode, const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents) { QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); m_program->bind(); @@ -95,7 +95,7 @@ void GLShaderSimple::draw(unsigned int mode, const QMatrix4x4& transformMatrix, f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); f->glLineWidth(1.0f); f->glEnableVertexAttribArray(0); // vertex - f->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices); + f->glVertexAttribPointer(0, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); f->glDrawArrays(mode, 0, nbVertices); f->glDisableVertexAttribArray(0); m_program->release(); diff --git a/sdrgui/gui/glshadersimple.h b/sdrgui/gui/glshadersimple.h index 19a4bfd2c..f52cdd519 100644 --- a/sdrgui/gui/glshadersimple.h +++ b/sdrgui/gui/glshadersimple.h @@ -35,15 +35,15 @@ public: ~GLShaderSimple(); void initializeGL(); - void drawPoints(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices); - void drawPolyline(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices); - void drawSegments(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices); - void drawContour(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices); - void drawSurface(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices); + void drawPoints(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents=2); + void drawPolyline(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents=2); + void drawSegments(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents=2); + void drawContour(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents=2); + void drawSurface(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents=2); void cleanup(); private: - void draw(unsigned int mode, const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices); + void draw(unsigned int mode, const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents); QOpenGLShaderProgram *m_program; int m_matrixLoc; diff --git a/sdrgui/gui/glshaderspectrogram.cpp b/sdrgui/gui/glshaderspectrogram.cpp new file mode 100644 index 000000000..f6da94599 --- /dev/null +++ b/sdrgui/gui/glshaderspectrogram.cpp @@ -0,0 +1,758 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2016 Edouard Griffiths, F4EXB. // +// Copyright (C) 2022 Jon Beniston, M7RCE // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "gui/glshaderspectrogram.h" +#include "util/colormap.h" + +GLShaderSpectrogram::GLShaderSpectrogram() : + m_programShaded(nullptr), + m_programSimple(nullptr), + m_texture(nullptr), + m_textureId(0), + m_colorMapTexture(nullptr), + m_colorMapTextureId(0), + m_programForLocs(nullptr), + m_textureTransformLoc(0), + m_vertexTransformLoc(0), + m_textureLoc(0), + m_limitLoc(0), + m_brightnessLoc(0), + m_colorMapLoc(0), + m_lightDirLoc(0), + m_lightPosLoc(0), + m_useImmutableStorage(true), + m_vertexBuf(QOpenGLBuffer::VertexBuffer), + m_index0Buf(QOpenGLBuffer::IndexBuffer), + m_index1Buf(QOpenGLBuffer::IndexBuffer), + m_translateX(0.0), + m_translateY(0.0), + m_translateZ(0.0), + m_rotX(-45.0), + m_rotY(0.0), + m_rotZ(0.0), + m_scaleX(1.0), + m_scaleY(1.0), + m_scaleZ(1.0), + m_userScaleZ(1.0), + m_verticalAngle(45.0f), + m_aspectRatio(1600.0/1200.0), + m_lightTranslateX(0.0), + m_lightTranslateY(0.0), + m_lightTranslateZ(0.0), + m_lightRotX(0.0), + m_lightRotY(0.0), + m_lightRotZ(0.0), + m_gridElements(1024) +{ +} + +GLShaderSpectrogram::~GLShaderSpectrogram() +{ + cleanup(); +} + +void GLShaderSpectrogram::initializeGL() +{ + initializeOpenGLFunctions(); + m_useImmutableStorage = useImmutableStorage(); + qDebug() << "GLShaderSpectrogram::initializeGL: m_useImmutableStorage: " << m_useImmutableStorage; + + m_programShaded = new QOpenGLShaderProgram; + if (!m_programShaded->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShader)) { + qDebug() << "GLShaderSpectrogram::initializeGL: error in vertex shader: " << m_programShaded->log(); + } + if (!m_programShaded->addShaderFromSourceCode(QOpenGLShader::Geometry, m_geometryShader)) { + qDebug() << "GLShaderSpectrogram::initializeGL: error in geometry shader: " << m_programShaded->log(); + } + if (!m_programShaded->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderShaded)) { + qDebug() << "GLShaderSpectrogram::initializeGL: error in fragment shader: " << m_programShaded->log(); + } + if (!m_programShaded->link()) { + qDebug() << "GLShaderSpectrogram::initializeGL: error linking shader: " << m_programShaded->log(); + } + + m_programSimple = new QOpenGLShaderProgram; + if (!m_programSimple->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShader)) { + qDebug() << "GLShaderSpectrogram::initializeGL: error in vertex shader: " << m_programSimple->log(); + } + if (!m_programSimple->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSimple)) { + qDebug() << "GLShaderSpectrogram::initializeGL: error in fragment shader: " << m_programSimple->log(); + } + if (!m_programSimple->link()) { + qDebug() << "GLShaderSpectrogram::initializeGL: error linking shader: " << m_programSimple->log(); + } +} + +void GLShaderSpectrogram::initGrid(int elements) +{ + m_gridElements = std::min(elements, 4096); // Limit to keep memory requirements realistic + qDebug() << "GLShaderSpectrogram::initGrid: requested: " << elements << " actual: " << m_gridElements; + int e1 = m_gridElements+1; + + // Grid vertices + std::vector vertices(e1 * e1); + + for (int i = 0; i < e1; i++) + { + for (int j = 0; j < e1; j++) + { + vertices[i*e1+j].setX(j / (float)m_gridElements); + vertices[i*e1+j].setY(i / (float)m_gridElements); + } + } + + m_vertexBuf.setUsagePattern(QOpenGLBuffer::StaticDraw); + m_vertexBuf.create(); + + m_index0Buf.setUsagePattern(QOpenGLBuffer::StaticDraw); + m_index0Buf.create(); + + m_index1Buf.setUsagePattern(QOpenGLBuffer::StaticDraw); + m_index1Buf.create(); + + m_vertexBuf.bind(); + m_vertexBuf.allocate(&vertices[0], vertices.size() * sizeof(QVector2D)); + + // Create an array of indices into the vertex array that traces both horizontal and vertical lines + std::vector indices(m_gridElements * m_gridElements * 6); + int i = 0; + + for (int y = 0; y < e1; y++) { + for (int x = 0; x < m_gridElements; x++) { + indices[i++] = y * (e1) + x; + indices[i++] = y * (e1) + x + 1; + } + } + + for (int x = 0; x < e1; x++) { + for (int y = 0; y < m_gridElements; y++) { + indices[i++] = y * (e1) + x; + indices[i++] = (y + 1) * (e1) + x; + } + } + + m_index0Buf.bind(); + m_index0Buf.allocate(&indices[0], m_gridElements * (e1) * 4 * sizeof(GLuint)); + + // Create another array of indices that describes all the triangles needed to create a completely filled surface + i = 0; + + for (int y = 0; y < m_gridElements; y++) { + for (int x = 0; x < m_gridElements; x++) { + indices[i++] = y * (e1) + x; + indices[i++] = y * (e1) + x + 1; + indices[i++] = (y + 1) * (e1) + x + 1; + + indices[i++] = y * (e1) + x; + indices[i++] = (y + 1) * (e1) + x + 1; + indices[i++] = (y + 1) * (e1) + x; + } + } + + m_index1Buf.bind(); + m_index1Buf.allocate(&indices[0], indices.size() * sizeof(GLuint)); + + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + f->glBindBuffer(GL_ARRAY_BUFFER, 0); + f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); +} + +void GLShaderSpectrogram::initColorMapTexture(const QString &colorMapName) +{ + if (m_useImmutableStorage) { + initColorMapTextureImmutable(colorMapName); + } else { + initColorMapTextureMutable(colorMapName); + } +} + +void GLShaderSpectrogram::initColorMapTextureImmutable(const QString &colorMapName) +{ + if (!m_colorMapTexture) + { + m_colorMapTexture = new QOpenGLTexture(QOpenGLTexture::Target1D); + m_colorMapTexture->setFormat(QOpenGLTexture::RGB32F); + m_colorMapTexture->setSize(256); + m_colorMapTexture->allocateStorage(); + m_colorMapTexture->setMinificationFilter(QOpenGLTexture::Linear); + m_colorMapTexture->setMagnificationFilter(QOpenGLTexture::Linear); + m_colorMapTexture->setWrapMode(QOpenGLTexture::ClampToEdge); + } + + GLfloat *colorMap = (GLfloat *)ColorMap::getColorMap(colorMapName); + if (colorMap) { + m_colorMapTexture->setData(QOpenGLTexture::RGB, QOpenGLTexture::Float32, colorMap); + } else { + qDebug() << "GLShaderSpectrogram::initColorMapTextureImmutable: colorMap " << colorMapName << " not supported"; + } +} + +void GLShaderSpectrogram::initColorMapTextureMutable(const QString &colorMapName) +{ + if (m_colorMapTextureId) + { + glDeleteTextures(1, &m_colorMapTextureId); + m_colorMapTextureId = 0; + } + + glGenTextures(1, &m_colorMapTextureId); + glBindTexture(GL_TEXTURE_1D, m_colorMapTextureId); + GLfloat *colorMap = (GLfloat *)ColorMap::getColorMap(colorMapName); + if (colorMap) { + glTexImage1D(GL_TEXTURE_1D, 0, GL_RGB, 256, 0, GL_RGB, GL_FLOAT, colorMap); + } else { + qDebug() << "GLShaderSpectrogram::initColorMapTextureMutable: colorMap " << colorMapName << " not supported"; + } + + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_S, QOpenGLTexture::Repeat); + glTexParameteri(GL_TEXTURE_1D, GL_TEXTURE_WRAP_T, QOpenGLTexture::Repeat); +} + +void GLShaderSpectrogram::initTexture(const QImage& image) +{ + if (m_useImmutableStorage) { + initTextureImmutable(image); + } else { + initTextureMutable(image); + } + initGrid(image.width()); +} + +void GLShaderSpectrogram::initTextureImmutable(const QImage& image) +{ + if (m_texture) { + delete m_texture; + } + + m_texture = new QOpenGLTexture(image); + + m_texture->setMinificationFilter(QOpenGLTexture::Linear); + m_texture->setMagnificationFilter(QOpenGLTexture::Linear); + m_texture->setWrapMode(QOpenGLTexture::Repeat); +} + +void GLShaderSpectrogram::initTextureMutable(const QImage& image) +{ + if (m_textureId) + { + glDeleteTextures(1, &m_textureId); + m_textureId = 0; + } + + glGenTextures(1, &m_textureId); + glBindTexture(GL_TEXTURE_2D, m_textureId); + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, + image.width(), image.height(), 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image.constScanLine(0)); + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, QOpenGLTexture::Repeat); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, QOpenGLTexture::Repeat); +} + +void GLShaderSpectrogram::subTexture(int xOffset, int yOffset, int width, int height, const void *pixels) +{ + if (m_useImmutableStorage) { + subTextureImmutable(xOffset, yOffset, width, height, pixels); + } else { + subTextureMutable(xOffset, yOffset, width, height, pixels); + } +} + +void GLShaderSpectrogram::subTextureImmutable(int xOffset, int yOffset, int width, int height, const void *pixels) +{ + if (!m_texture) + { + qDebug("GLShaderSpectrogram::subTextureImmutable: no texture defined. Doing nothing"); + return; + } + + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + m_texture->bind(); + f->glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels); +} + +void GLShaderSpectrogram::subTextureMutable(int xOffset, int yOffset, int width, int height, const void *pixels) +{ + if (!m_textureId) + { + qDebug("GLShaderSpectrogram::subTextureMutable: no texture defined. Doing nothing"); + return; + } + + glBindTexture(GL_TEXTURE_2D, m_textureId); + glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels); +} + +void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, float textureOffset, bool invert) +{ + if ((m_useImmutableStorage && !m_texture) || (!m_useImmutableStorage && !m_textureId)) + { + qDebug("GLShaderSpectrogram::drawSurface: no texture defined. Doing nothing"); + return; + } + + QOpenGLShaderProgram *program; + if (style == SpectrumSettings::Shaded) { + program = m_programShaded; + } else { + program = m_programSimple; + } + + // Note that translation to the origin and rotation + // needs to be performed in reverse order to what you + // might normally expect + // See: https://bugreports.qt.io/browse/QTBUG-20752 + + QMatrix4x4 vertexTransform; + vertexTransform.translate(0.0f, 0.0f, -1.65f); + applyScaleRotate(vertexTransform); + vertexTransform.translate(-0.5f, -0.5f, 0.0f); + applyPerspective(vertexTransform); + + float rot = invert ? 1.0 : -1.0; + QMatrix4x4 textureTransform( + 1.0, 0.0, 0.0, 0.0, + 0.0, rot, 0.0, textureOffset, + 0.0, 0.0, rot, 0.0, + 0.0, 0.0, 0.0, 1.0); // Use this to move texture for each row of data + + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + program->bind(); + + if (program != m_programForLocs) + { + m_textureTransformLoc = program->uniformLocation("textureTransform"); + m_vertexTransformLoc = program->uniformLocation("vertexTransform"); + m_textureLoc = program->uniformLocation("texture"); + m_limitLoc = program->uniformLocation("limit"); + m_brightnessLoc = program->uniformLocation("brightness"); + m_colorMapLoc = program->uniformLocation("colorMap"); + m_lightDirLoc = program->uniformLocation("lightDir"); + m_lightPosLoc = program->uniformLocation("lightPos"); + m_programForLocs = program; + } + + program->setUniformValue(m_vertexTransformLoc, vertexTransform); + program->setUniformValue(m_textureTransformLoc, textureTransform); + + if (m_useImmutableStorage) + { + m_texture->bind(); + glActiveTexture(GL_TEXTURE1); + m_colorMapTexture->bind(); + glActiveTexture(GL_TEXTURE0); + } + else + { + glBindTexture(GL_TEXTURE_2D, m_textureId); + glActiveTexture(GL_TEXTURE1); + glBindTexture(GL_TEXTURE_1D, m_colorMapTextureId); + glActiveTexture(GL_TEXTURE0); + } + + program->setUniformValue(m_textureLoc, 0); // set uniform to texture unit? + program->setUniformValue(m_colorMapLoc, 1); + + program->setUniformValue(m_limitLoc, 1.5f*1.0f/(float)(m_gridElements)); + + if (style == SpectrumSettings::Outline) + { + // When drawing the outline, slightly darken the triangles + // so grid is a bit more visible + program->setUniformValue(m_brightnessLoc, 0.85f); + } + else + { + program->setUniformValue(m_brightnessLoc, 1.0f); + } + + if (style == SpectrumSettings::Shaded) + { + QMatrix4x4 matrix; + matrix.rotate(m_lightRotX, 1.0f, 0.0f, 0.0f); + matrix.rotate(m_lightRotY, 0.0f, 1.0f, 0.0f); + matrix.rotate(m_lightRotZ, 0.0f, 0.0f, 1.0f); + QVector3D vector = matrix * QVector3D(0.0f, 0.0f, -1.0f); + GLfloat lightDir[3] = {vector.x(), vector.y(), vector.z()}; + GLfloat lightPos[3] = {m_lightTranslateX, m_lightTranslateY, m_lightTranslateZ}; + program->setUniformValueArray(m_lightDirLoc, lightDir, 1, 3); + program->setUniformValueArray(m_lightPosLoc, lightPos, 1, 3); + } + + f->glEnable(GL_DEPTH_TEST); + + f->glPolygonOffset(1, 0); + f->glEnable(GL_POLYGON_OFFSET_FILL); + + int attribute_coord2d = program->attributeLocation("coord2d"); + f->glEnableVertexAttribArray(attribute_coord2d); + m_vertexBuf.bind(); + f->glVertexAttribPointer(attribute_coord2d, 2, GL_FLOAT, GL_FALSE, 0, 0); + + m_index1Buf.bind(); + switch (style) + { + case SpectrumSettings::Points: + f->glDrawElements(GL_POINTS, m_gridElements * m_gridElements * 6, GL_UNSIGNED_INT, 0); + break; + case SpectrumSettings::Lines: + f->glDrawElements(GL_LINES, m_gridElements * m_gridElements * 6, GL_UNSIGNED_INT, 0); + break; + case SpectrumSettings::Solid: + case SpectrumSettings::Outline: + case SpectrumSettings::Shaded: + f->glDrawElements(GL_TRIANGLES, m_gridElements * m_gridElements * 6, GL_UNSIGNED_INT, 0); + break; + } + + f->glPolygonOffset(0, 0); + f->glDisable(GL_POLYGON_OFFSET_FILL); + + if (style == SpectrumSettings::Outline) + { + // Draw the outline + program->setUniformValue(m_brightnessLoc, 1.5f); + m_index0Buf.bind(); + f->glDrawElements(GL_LINES, m_gridElements * (m_gridElements+1) * 4, GL_UNSIGNED_INT, 0); + } + + f->glDisableVertexAttribArray(attribute_coord2d); + // Need to do this, otherwise nothing else is drawn... + f->glBindBuffer(GL_ARRAY_BUFFER, 0); + f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + + // If this is left enabled, channel markers aren't drawn properly + f->glDisable(GL_DEPTH_TEST); + + program->release(); +} + +void GLShaderSpectrogram::cleanup() +{ + if (!QOpenGLContext::currentContext()) { + return; + } + + if (m_programShaded) + { + delete m_programShaded; + m_programShaded = nullptr; + } + + if (m_programSimple) + { + delete m_programSimple; + m_programSimple = nullptr; + } + + m_programForLocs = nullptr; + + if (m_texture) + { + delete m_texture; + m_texture = nullptr; + } + + if (m_textureId) + { + glDeleteTextures(1, &m_textureId); + m_textureId = 0; + } + + if (m_colorMapTextureId) + { + glDeleteTextures(1, &m_colorMapTextureId); + m_colorMapTextureId = 0; + } + + if (m_colorMapTexture) + { + delete m_colorMapTexture; + m_colorMapTexture = nullptr; + } +} + +bool GLShaderSpectrogram::useImmutableStorage() +{ + QOpenGLContext* ctx = QOpenGLContext::currentContext(); + QSurfaceFormat sf = ctx->format(); + + if (sf.version() >= qMakePair(4, 2) + || ctx->hasExtension(QByteArrayLiteral("GL_ARB_texture_storage")) + || ctx->hasExtension(QByteArrayLiteral("GL_EXT_texture_storage"))) + { + void (QOPENGLF_APIENTRYP glTexStorage2D)( + GLenum target, GLsizei levels, GLenum internalFormat, GLsizei width, GLsizei height); + glTexStorage2D = reinterpret_cast(ctx->getProcAddress("glTexStorage2D")); + int data = 0; + GLuint textureId; + glGenTextures(1, &textureId); + glBindTexture(GL_TEXTURE_2D, textureId); + glTexStorage2D(GL_TEXTURE_2D, 1, GL_RGBA8, 1, 1); + glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, GL_RGBA, GL_UNSIGNED_BYTE, &data); + GLenum err = glGetError(); + glDeleteTextures(1, &textureId); + return err == GL_NO_ERROR; + } + + return false; +} + +void GLShaderSpectrogram::translateX(float distance) +{ + m_translateX += distance; +} + +void GLShaderSpectrogram::translateY(float distance) +{ + m_translateY += distance; +} + +void GLShaderSpectrogram::translateZ(float distance) +{ + m_translateZ += distance; +} + +void GLShaderSpectrogram::rotateX(float degrees) +{ + m_rotX += degrees; +} + +void GLShaderSpectrogram::rotateY(float degrees) +{ + m_rotY += degrees; +} + +void GLShaderSpectrogram::rotateZ(float degrees) +{ + m_rotZ += degrees; +} + +void GLShaderSpectrogram::setScaleX(float factor) +{ + m_scaleX = factor; +} + +void GLShaderSpectrogram::setScaleY(float factor) +{ + m_scaleY = factor; +} + +void GLShaderSpectrogram::setScaleZ(float factor) +{ + m_scaleZ = factor; +} + +void GLShaderSpectrogram::userScaleZ(float factor) +{ + m_userScaleZ *= factor; + if ((m_userScaleZ < 0.1) && (factor < 1.0)) { + m_userScaleZ = 0.0; + } else if ((m_userScaleZ == 0.0) && (factor > 1.0)) { + m_userScaleZ = 0.1; + } +} + +void GLShaderSpectrogram::reset() +{ + // Don't reset m_scaleX, m_scaleY and m_scaleZ, m_aspectRatio + // as they are not set directly by user, but depend on window size + m_translateX = 0.0f; + m_translateY = 0.0f; + m_translateZ = 0.0f; + m_rotX = -45.0f; + m_rotY = 0.0f; + m_rotZ = 0.0f; + m_userScaleZ = 1.0f; + m_verticalAngle = 45.0f; + m_lightTranslateX = 0.0f; + m_lightTranslateY = 0.0f; + m_lightTranslateZ = 0.0f; + m_lightRotX = 0.0f; + m_lightRotY = 0.0f; + m_lightRotZ = 0.0f; + setPerspective(); +} + +void GLShaderSpectrogram::setAspectRatio(float aspectRatio) +{ + m_aspectRatio = aspectRatio; + setPerspective(); +} + +void GLShaderSpectrogram::verticalAngle(float degrees) +{ + m_verticalAngle += degrees; + m_verticalAngle = std::max(1.0f, m_verticalAngle); + m_verticalAngle = std::min(179.0f, m_verticalAngle); + setPerspective(); +} + +void GLShaderSpectrogram::setPerspective() +{ + m_perspective.setToIdentity(); + m_perspective.perspective(m_verticalAngle, m_aspectRatio, 0.1, 7.0); +} + +void GLShaderSpectrogram::lightTranslateX(float distance) +{ + m_lightTranslateX += distance; +} + +void GLShaderSpectrogram::lightTranslateY(float distance) +{ + m_lightTranslateY += distance; +} + +void GLShaderSpectrogram::lightTranslateZ(float distance) +{ + m_lightTranslateZ += distance; +} + +void GLShaderSpectrogram::lightRotateX(float degrees) +{ + m_lightRotX += degrees; +} + +void GLShaderSpectrogram::lightRotateY(float degrees) +{ + m_lightRotY += degrees; +} + +void GLShaderSpectrogram::lightRotateZ(float degrees) +{ + m_lightRotZ += degrees; +} + +void GLShaderSpectrogram::applyScaleRotate(QMatrix4x4 &matrix) +{ + // As above, this is in reverse + matrix.translate(m_translateX, m_translateY, m_translateZ); + matrix.rotate(m_rotX, 1.0f, 0.0f, 0.0f); + matrix.rotate(m_rotY, 0.0f, 1.0f, 0.0f); + matrix.rotate(m_rotZ, 0.0f, 0.0f, 1.0f); + matrix.scale(m_scaleX, m_scaleY, m_scaleZ * m_userScaleZ); +} + +void GLShaderSpectrogram::applyPerspective(QMatrix4x4 &matrix) +{ + matrix = m_perspective * matrix; +} + +// The clamp is to prevent old data affecting new data (And vice versa), +// which can happen where the texture repeats - might be a better way to do it +const QString GLShaderSpectrogram::m_vertexShader = QString( + "attribute vec2 coord2d;\n" + "varying vec4 coord;\n" + "varying float lightDistance;\n" + "uniform mat4 textureTransform;\n" + "uniform mat4 vertexTransform;\n" + "uniform sampler2D texture;\n" + "uniform float limit;\n" + "uniform vec3 lightPos;\n" + "void main(void) {\n" + " coord = textureTransform * vec4(clamp(coord2d, limit, 1.0-limit), 0, 1);\n" + " coord.z = (texture2D(texture, coord.xy).r);\n" + " gl_Position = vertexTransform * vec4(coord2d, coord.z, 1);\n" + " lightDistance = length(lightPos - gl_Position.xyz);\n" + "}\n" + ); + +// We need to use a geometry shader to calculate the normals, as they are only +// determined after z has been calculated for the verticies in the vertex shader +const QString GLShaderSpectrogram::m_geometryShader = QString( + "#version 330\n" + "layout(triangles) in;\n" + "layout(triangle_strip, max_vertices=3) out;\n" + "in vec4 coord[];\n" + "in float lightDistance[];\n" + "out vec4 coord2;\n" + "out vec3 normal;\n" + "out float lightDistance2;\n" + "void main(void) {\n" + " vec3 a = (gl_in[1].gl_Position - gl_in[0].gl_Position).xyz;\n" + " vec3 b = (gl_in[2].gl_Position - gl_in[0].gl_Position).xyz;\n" + " vec3 N = normalize(cross(b, a));\n" + " for(int i=0; i < gl_in.length(); ++i)\n" + " {\n" + " gl_Position = gl_in[i].gl_Position;\n" + " normal = N;\n" + " coord2 = coord[i];\n" + " lightDistance2 = lightDistance[i];\n" + " EmitVertex( );\n" + " }\n" + " EndPrimitive( );\n" + "}\n" + ); + +const QString GLShaderSpectrogram::m_fragmentShaderShaded = QString( + "varying vec4 coord2;\n" + "varying vec3 normal;\n" + "varying float lightDistance2;\n" + "uniform sampler1D colorMap;\n" + "uniform vec3 lightDir;\n" + "void main(void) {\n" + " float factor;\n" + " if (gl_FrontFacing)\n" + " factor = 1.0;\n" + " else\n" + " factor = 0.5;\n" + " float ambient = 0.4;\n" + " vec3 color;\n" + " color.r = texture1D(colorMap, coord2.z).r;\n" + " color.g = texture1D(colorMap, coord2.z).g;\n" + " color.b = texture1D(colorMap, coord2.z).b;\n" + " float cosTheta = max(0.0, dot(normal, lightDir));\n" + " float d2 = max(1.0, lightDistance2*lightDistance2);\n" + " vec3 relection = (ambient * color + color * cosTheta / d2) * factor;\n" + " gl_FragColor[0] = relection.r;\n" + " gl_FragColor[1] = relection.g;\n" + " gl_FragColor[2] = relection.b;\n" + " gl_FragColor[3] = 1.0;\n" + "}\n" + ); + +const QString GLShaderSpectrogram::m_fragmentShaderSimple = QString( + "varying vec4 coord;\n" + "uniform float brightness;\n" + "uniform sampler1D colorMap;\n" + "void main(void) {\n" + " float factor;\n" + " if (gl_FrontFacing)\n" + " factor = 1.0;\n" + " else\n" + " factor = 0.5;\n" + " gl_FragColor[0] = texture1D(colorMap, coord.z).r * brightness * factor;\n" + " gl_FragColor[1] = texture1D(colorMap, coord.z).g * brightness * factor;\n" + " gl_FragColor[2] = texture1D(colorMap, coord.z).b * brightness * factor;\n" + " gl_FragColor[3] = 1.0;\n" + "}\n" + ); diff --git a/sdrgui/gui/glshaderspectrogram.h b/sdrgui/gui/glshaderspectrogram.h new file mode 100644 index 000000000..786208634 --- /dev/null +++ b/sdrgui/gui/glshaderspectrogram.h @@ -0,0 +1,128 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2016 Edouard Griffiths, F4EXB. // +// Copyright (C) 2022 Jon Beniston, M7RCE // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef INCLUDE_GUI_GLSHADERSPECTROGRAM_H_ +#define INCLUDE_GUI_GLSHADERSPECTROGRAM_H_ + +#include +#include +#include + +#include "export.h" +#include "dsp/spectrumsettings.h" + +class QOpenGLShaderProgram; +class QMatrix4x4; +class QImage; + +class SDRGUI_API GLShaderSpectrogram : protected QOpenGLFunctions +{ +public: + GLShaderSpectrogram(); + ~GLShaderSpectrogram(); + + void initializeGL(); + void initColorMapTexture(const QString &colorMapName); + void initTexture(const QImage& image); + void subTexture(int xOffset, int yOffset, int width, int height, const void *pixels); + void drawSurface(SpectrumSettings::SpectrogramStyle style, float textureOffset, bool invert); + void cleanup(); + void translateX(float distance); + void translateY(float distance); + void translateZ(float distance); + void rotateX(float degrees); + void rotateY(float degrees); + void rotateZ(float degrees); + void setScaleX(float factor); + void setScaleY(float factor); + void setScaleZ(float factor); + void userScaleZ(float factor); + void reset(); + void setAspectRatio(float aspectRatio); + void verticalAngle(float degrees); + void lightTranslateX(float distance); + void lightTranslateY(float distance); + void lightTranslateZ(float distance); + void lightRotateX(float degrees); + void lightRotateY(float degrees); + void lightRotateZ(float degrees); + void applyScaleRotate(QMatrix4x4 &matrix); + void applyPerspective(QMatrix4x4 &matrix); + +private: + void initColorMapTextureMutable(const QString &colorMapName); + void initColorMapTextureImmutable(const QString &colorMapName); + void initTextureImmutable(const QImage& image); + void subTextureImmutable(int xOffset, int yOffset, int width, int height, const void *pixels); + void initTextureMutable(const QImage& image); + void subTextureMutable(int xOffset, int yOffset, int width, int height, const void *pixels); + bool useImmutableStorage(); + void initGrid(int elements); + void setPerspective(); + + QOpenGLShaderProgram *m_programShaded; + QOpenGLShaderProgram *m_programSimple; + QOpenGLTexture *m_texture; + unsigned int m_textureId; + QOpenGLTexture *m_colorMapTexture; + unsigned int m_colorMapTextureId; + + QOpenGLShaderProgram *m_programForLocs; // Which program the locations are for + int m_textureTransformLoc; + int m_vertexTransformLoc; + int m_textureLoc; + int m_limitLoc; + int m_brightnessLoc; + int m_colorMapLoc; + int m_lightDirLoc; + int m_lightPosLoc; + + bool m_useImmutableStorage; + static const QString m_vertexShader; + static const QString m_geometryShader; + static const QString m_fragmentShaderShaded; + static const QString m_fragmentShaderSimple; + + QOpenGLBuffer m_vertexBuf; + QOpenGLBuffer m_index0Buf; + QOpenGLBuffer m_index1Buf; + + float m_translateX; + float m_translateY; + float m_translateZ; + float m_rotX; + float m_rotY; + float m_rotZ; + float m_scaleX; + float m_scaleY; + float m_scaleZ; + float m_userScaleZ; + float m_verticalAngle; + float m_aspectRatio; + float m_lightTranslateX; + float m_lightTranslateY; + float m_lightTranslateZ; + float m_lightRotX; + float m_lightRotY; + float m_lightRotZ; + QMatrix4x4 m_perspective; + int m_gridElements; + +}; + +#endif /* INCLUDE_GUI_GLSHADERSPECTROGRAM_H_ */ diff --git a/sdrgui/gui/glshadertextured.cpp b/sdrgui/gui/glshadertextured.cpp index 4c1c28751..fdd20198e 100644 --- a/sdrgui/gui/glshadertextured.cpp +++ b/sdrgui/gui/glshadertextured.cpp @@ -144,16 +144,16 @@ void GLShaderTextured::subTextureMutable(int xOffset, int yOffset, int width, in glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); } -void GLShaderTextured::drawSurface(const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices) +void GLShaderTextured::drawSurface(const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices, int nbComponents) { if (m_useImmutableStorage) { - draw(GL_TRIANGLE_FAN, transformMatrix, textureCoords, vertices, nbVertices); + draw(GL_TRIANGLE_FAN, transformMatrix, textureCoords, vertices, nbVertices, nbComponents); } else { - drawMutable(GL_TRIANGLE_FAN, transformMatrix, textureCoords, vertices, nbVertices); + drawMutable(GL_TRIANGLE_FAN, transformMatrix, textureCoords, vertices, nbVertices, nbComponents); } } -void GLShaderTextured::draw(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices) +void GLShaderTextured::draw(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices, int nbComponents) { if (!m_texture) { @@ -167,7 +167,7 @@ void GLShaderTextured::draw(unsigned int mode, const QMatrix4x4& transformMatrix m_texture->bind(); m_program->setUniformValue(m_textureLoc, 0); // Use texture unit 0 which magically contains our texture f->glEnableVertexAttribArray(0); // vertex - f->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices); + f->glVertexAttribPointer(0, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); f->glEnableVertexAttribArray(1); // texture coordinates f->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); f->glDrawArrays(mode, 0, nbVertices); @@ -175,7 +175,7 @@ void GLShaderTextured::draw(unsigned int mode, const QMatrix4x4& transformMatrix m_program->release(); } -void GLShaderTextured::drawMutable(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices) +void GLShaderTextured::drawMutable(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices, int nbComponents) { if (!m_textureId) { @@ -188,7 +188,7 @@ void GLShaderTextured::drawMutable(unsigned int mode, const QMatrix4x4& transfor glBindTexture(GL_TEXTURE_2D, m_textureId); m_program->setUniformValue(m_textureLoc, 0); // Use texture unit 0 which magically contains our texture glEnableVertexAttribArray(0); // vertex - glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices); + glVertexAttribPointer(0, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); glEnableVertexAttribArray(1); // texture coordinates glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); glDrawArrays(mode, 0, nbVertices); diff --git a/sdrgui/gui/glshadertextured.h b/sdrgui/gui/glshadertextured.h index d94b432a5..a938a159b 100644 --- a/sdrgui/gui/glshadertextured.h +++ b/sdrgui/gui/glshadertextured.h @@ -41,12 +41,12 @@ public: void initializeGL(); void initTexture(const QImage& image, QOpenGLTexture::WrapMode wrapMode = QOpenGLTexture::Repeat); void subTexture(int xOffset, int yOffset, int width, int height, const void *pixels); - void drawSurface(const QMatrix4x4& transformMatrix, GLfloat* textureCoords, GLfloat *vertices, int nbVertices); + void drawSurface(const QMatrix4x4& transformMatrix, GLfloat* textureCoords, GLfloat *vertices, int nbVertices, int nbComponents=2); void cleanup(); private: - void draw(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices); - void drawMutable(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices); + void draw(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices, int nbComponents); + void drawMutable(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices, int nbComponents); void initTextureImmutable(const QImage& image, QOpenGLTexture::WrapMode wrapMode = QOpenGLTexture::Repeat); void subTextureImmutable(int xOffset, int yOffset, int width, int height, const void *pixels); void initTextureMutable(const QImage& image, QOpenGLTexture::WrapMode wrapMode = QOpenGLTexture::Repeat); diff --git a/sdrgui/gui/glspectrum.cpp b/sdrgui/gui/glspectrum.cpp index 4004ed4c5..769450dde 100644 --- a/sdrgui/gui/glspectrum.cpp +++ b/sdrgui/gui/glspectrum.cpp @@ -23,8 +23,10 @@ #include #include #include +#include "maincore.h" #include "dsp/spectrumvis.h" #include "gui/glspectrum.h" +#include "settings/mainsettings.h" #include "util/messagequeue.h" #include "util/db.h" @@ -79,6 +81,16 @@ GLSpectrum::GLSpectrum(QWidget* parent) : m_displayWaterfall(true), m_ssbSpectrum(false), m_lsbDisplay(false), + m_3DSpectrogramBuffer(nullptr), + m_3DSpectrogramBufferPos(0), + m_3DSpectrogramTextureHeight(-1), + m_3DSpectrogramTexturePos(0), + m_display3DSpectrogram(false), + m_rotate3DSpectrogram(false), + m_pan3DSpectrogram(false), + m_scaleZ3DSpectrogram(false), + m_3DSpectrogramStyle(SpectrumSettings::Outline), + m_3DSpectrogramColorMap("Angel"), m_histogramBuffer(nullptr), m_histogram(nullptr), m_displayHistogram(true), @@ -91,8 +103,18 @@ GLSpectrum::GLSpectrum(QWidget* parent) : m_calibrationGain(1.0), m_calibrationShiftdB(0.0), m_calibrationInterpMode(SpectrumSettings::CalibInterpLinear), - m_messageQueueToGUI(nullptr) + m_messageQueueToGUI(nullptr), + m_openGLLogger(nullptr) { + // Enable multisampling anti-aliasing (MSAA) + int multisamples = MainCore::instance()->getSettings().getMultisampling(); + if (multisamples > 0) + { + QSurfaceFormat format; + format.setSamples(multisamples); + setFormat(format); + } + setObjectName("GLSpectrum"); setAutoFillBackground(false); setAttribute(Qt::WA_OpaquePaintEvent, true); @@ -179,6 +201,10 @@ GLSpectrum::GLSpectrum(QWidget* parent) : m_timer.setTimerType(Qt::PreciseTimer); connect(&m_timer, SIGNAL(timeout()), this, SLOT(tick())); m_timer.start(m_fpsPeriodMs); + + // Handle KeyEvents + setFocusPolicy(Qt::StrongFocus); + installEventFilter(this); } GLSpectrum::~GLSpectrum() @@ -191,6 +217,12 @@ GLSpectrum::~GLSpectrum() m_waterfallBuffer = nullptr; } + if (m_3DSpectrogramBuffer) + { + delete m_3DSpectrogramBuffer; + m_3DSpectrogramBuffer = nullptr; + } + if (m_histogramBuffer) { delete m_histogramBuffer; @@ -202,6 +234,12 @@ GLSpectrum::~GLSpectrum() delete[] m_histogram; m_histogram = nullptr; } + + if (m_openGLLogger) + { + delete m_openGLLogger; + m_openGLLogger = nullptr; + } } void GLSpectrum::setCenterFrequency(qint64 frequency) @@ -296,6 +334,31 @@ void GLSpectrum::setDisplayWaterfall(bool display) update(); } +void GLSpectrum::setDisplay3DSpectrogram(bool display) +{ + m_mutex.lock(); + m_display3DSpectrogram = display; + m_changesPending = true; + stopDrag(); + m_mutex.unlock(); + update(); +} + +void GLSpectrum::set3DSpectrogramStyle(SpectrumSettings::SpectrogramStyle style) +{ + m_3DSpectrogramStyle = style; + update(); +} + +void GLSpectrum::set3DSpectrogramColorMap(const QString &colorMap) +{ + m_mutex.lock(); + m_3DSpectrogramColorMap = colorMap; + m_changesPending = true; + m_mutex.unlock(); + update(); +} + void GLSpectrum::setSsbSpectrum(bool ssbSpectrum) { m_ssbSpectrum = ssbSpectrum; @@ -537,6 +600,7 @@ void GLSpectrum::newSpectrum(const Real *spectrum, int nbBins, int fftSize) } updateWaterfall(spectrum); + update3DSpectrogram(spectrum); updateHistogram(spectrum); } @@ -563,6 +627,29 @@ void GLSpectrum::updateWaterfall(const Real *spectrum) } } +void GLSpectrum::update3DSpectrogram(const Real *spectrum) +{ + if (m_3DSpectrogramBufferPos < m_3DSpectrogramBuffer->height()) + { + quint8* pix = (quint8*)m_3DSpectrogramBuffer->scanLine(m_3DSpectrogramBufferPos); + + for (int i = 0; i < m_nbBins; i++) + { + int v = (int)((spectrum[i] - m_referenceLevel) * 2.4 * 100.0 / m_powerRange + 240.0); + + if (v > 255) { + v = 255; + } else if (v < 0) { + v = 0; + } + + *pix++ = v; + } + + m_3DSpectrogramBufferPos++; + } +} + void GLSpectrum::updateHistogram(const Real *spectrum) { quint8* b = m_histogram; @@ -691,6 +778,27 @@ void GLSpectrum::initializeGL() else { qDebug() << "GLSpectrum::initializeGL: current context is invalid"; } + + if ( (MainCore::instance()->getSettings().getConsoleMinLogLevel() <= QtDebugMsg) + || (MainCore::instance()->getSettings().getFileMinLogLevel() <= QtDebugMsg)) + { + // Enable OpenGL debugging + QSurfaceFormat format = glCurrentContext->format(); + format.setOption(QSurfaceFormat::DebugContext); + glCurrentContext->setFormat(format); + + if (glCurrentContext->hasExtension(QByteArrayLiteral("GL_KHR_debug"))) + { + m_openGLLogger = new QOpenGLDebugLogger(this); + m_openGLLogger->initialize(); + connect(m_openGLLogger, &QOpenGLDebugLogger::messageLogged, this, &GLSpectrum::openGLDebug); + m_openGLLogger->startLogging(QOpenGLDebugLogger::SynchronousLogging); + } + else + { + qDebug() << "GLSpectrum::initializeGL: GL_KHR_debug not available"; + } + } } else { @@ -711,6 +819,14 @@ void GLSpectrum::initializeGL() m_glShaderHistogram.initializeGL(); m_glShaderTextOverlay.initializeGL(); m_glShaderInfo.initializeGL(); + m_glShaderSpectrogram.initializeGL(); + m_glShaderSpectrogramTimeScale.initializeGL(); + m_glShaderSpectrogramPowerScale.initializeGL(); +} + +void GLSpectrum::openGLDebug(const QOpenGLDebugMessage &debugMessage) +{ + qDebug() << "GLSpectrum::openGLDebug: " << debugMessage; } void GLSpectrum::resizeGL(int width, int height) @@ -753,11 +869,43 @@ void GLSpectrum::paintGL() QOpenGLFunctions *glFunctions = QOpenGLContext::currentContext()->functions(); glFunctions->glClearColor(0.0f, 0.0f, 0.0f, 0.0f); - glFunctions->glClear(GL_COLOR_BUFFER_BIT); + glFunctions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); - // paint waterfall - if (m_displayWaterfall) + QMatrix4x4 spectrogramGridMatrix; + spectrogramGridMatrix.translate(0.0f, 0.0f, -1.65f); + m_glShaderSpectrogram.applyScaleRotate(spectrogramGridMatrix); + spectrogramGridMatrix.translate(-0.5f, -0.5f, 0.0f); + m_glShaderSpectrogram.applyPerspective(spectrogramGridMatrix); + + if (m_display3DSpectrogram) { + // paint 3D spectrogram + if (m_3DSpectrogramTexturePos + m_3DSpectrogramBufferPos < m_3DSpectrogramTextureHeight) + { + m_glShaderSpectrogram.subTexture(0, m_3DSpectrogramTexturePos, m_nbBins, m_3DSpectrogramBufferPos, m_3DSpectrogramBuffer->scanLine(0)); + m_3DSpectrogramTexturePos += m_3DSpectrogramBufferPos; + } + else + { + int breakLine = m_3DSpectrogramTextureHeight - m_3DSpectrogramTexturePos; + int linesLeft = m_3DSpectrogramTexturePos + m_3DSpectrogramBufferPos - m_3DSpectrogramTextureHeight; + m_glShaderSpectrogram.subTexture(0, m_3DSpectrogramTexturePos, m_nbBins, breakLine, m_3DSpectrogramBuffer->scanLine(0)); + m_glShaderSpectrogram.subTexture(0, 0, m_nbBins, linesLeft, m_3DSpectrogramBuffer->scanLine(breakLine)); + m_3DSpectrogramTexturePos = linesLeft; + } + + m_3DSpectrogramBufferPos = 0; + + float prop_y = m_3DSpectrogramTexturePos / (m_3DSpectrogramTextureHeight - 1.0); + + // Temporarily reduce viewport to waterfall area so anything outside is clipped + glFunctions->glViewport(0, m_3DSpectrogramBottom, width(), m_waterfallHeight); + m_glShaderSpectrogram.drawSurface(m_3DSpectrogramStyle, prop_y, m_invertedWaterfall); + glFunctions->glViewport(0, 0, width(), height()); + } + else if (m_displayWaterfall) + { + // paint 2D waterfall { GLfloat vtx1[] = { 0, m_invertedWaterfall ? 0.0f : 1.0f, @@ -960,7 +1108,7 @@ void GLSpectrum::paintGL() } // paint frequency scale - if (m_displayWaterfall || m_displayMaxHold || m_displayCurrent || m_displayHistogram ) + if (m_displayWaterfall || m_displayMaxHold || m_displayCurrent || m_displayHistogram) { { GLfloat vtx1[] = { @@ -1015,6 +1163,74 @@ void GLSpectrum::paintGL() } } + // paint 3D spectrogram scales + if (m_display3DSpectrogram && m_displayGrid) + { + glFunctions->glViewport(0, m_3DSpectrogramBottom, width(), m_waterfallHeight); + { + float l = m_spectrogramTimePixmap.width() / (float) width(); + float r = m_rightMargin / (float) width(); + float h = m_frequencyPixmap.height() / (float) m_waterfallHeight; + + GLfloat vtx1[] = { + -l, -h, + 1+r, -h, + 1+r, 0, + -l, 0 + }; + GLfloat tex1[] = { + 0, 1, + 1, 1, + 1, 0, + 0, 0 + }; + + m_glShaderFrequencyScale.drawSurface(spectrogramGridMatrix, tex1, vtx1, 4); + } + + { + float w = m_spectrogramTimePixmap.width() / (float) width(); + float h = (m_bottomMargin/2) / (float) m_waterfallHeight; // m_bottomMargin is fm.ascent + + GLfloat vtx1[] = { + -w, 0.0-h, + 0, 0.0-h, + 0, 1.0+h, + -w, 1.0+h + }; + GLfloat tex1[] = { + 0, 1, + 1, 1, + 1, 0, + 0, 0 + }; + + m_glShaderSpectrogramTimeScale.drawSurface(spectrogramGridMatrix, tex1, vtx1, 4); + } + + { + float w = m_spectrogramPowerPixmap.width() / (float) width(); + float h = m_topMargin / (float) m_spectrogramPowerPixmap.height(); + + GLfloat vtx1[] = { + -w, 1.0, 0.0, + 0, 1.0, 0.0, + 0, 1.0, 1.0+h, + -w, 1.0, 1.0+h, + }; + GLfloat tex1[] = { + 0, 1, + 1, 1, + 1, 0, + 0, 0 + }; + + m_glShaderSpectrogramPowerScale.drawSurface(spectrogramGridMatrix, tex1, vtx1, 4, 3); + } + + glFunctions->glViewport(0, 0, width(), height()); + } + // paint max hold lines on top of histogram if (m_displayMaxHold) { @@ -1154,6 +1370,128 @@ void GLSpectrum::paintGL() } } + // paint 3D spectrogram grid - this is drawn on top of signal, so that appears slightly transparent + // x-axis is freq, y time and z power + if (m_displayGrid && m_display3DSpectrogram) + { + const ScaleEngine::TickList* tickList; + const ScaleEngine::Tick* tick; + + glFunctions->glViewport(0, m_3DSpectrogramBottom, width(), m_waterfallHeight); + + tickList = &m_powerScale.getTickList(); + { + GLfloat *q3 = m_q3TickPower.m_array; + int effectiveTicks = 0; + + for (int i= 0; i < tickList->count(); i++) + { + tick = &(*tickList)[i]; + + if (tick->major) + { + if (tick->textSize > 0) + { + float y = tick->pos / m_powerScale.getSize(); + q3[6*effectiveTicks] = 0.0; + q3[6*effectiveTicks+1] = 1.0; + q3[6*effectiveTicks+2] = y; + q3[6*effectiveTicks+3] = 1.0; + q3[6*effectiveTicks+4] = 1.0; + q3[6*effectiveTicks+5] = y; + effectiveTicks++; + } + } + } + + QVector4D color(1.0f, 1.0f, 1.0f, (float) m_displayGridIntensity / 100.0f); + m_glShaderSimple.drawSegments(spectrogramGridMatrix, color, q3, 2*effectiveTicks, 3); + } + + tickList = &m_timeScale.getTickList(); + { + GLfloat *q3 = m_q3TickTime.m_array; + int effectiveTicks = 0; + + for (int i= 0; i < tickList->count(); i++) + { + tick = &(*tickList)[i]; + + if (tick->major) + { + if (tick->textSize > 0) + { + float y = tick->pos / m_timeScale.getSize(); + q3[4*effectiveTicks] = 0.0; + q3[4*effectiveTicks+1] = 1.0 - y; + q3[4*effectiveTicks+2] = 1.0; + q3[4*effectiveTicks+3] = 1.0 - y; + effectiveTicks++; + } + } + } + + QVector4D color(1.0f, 1.0f, 1.0f, (float) m_displayGridIntensity / 100.0f); + m_glShaderSimple.drawSegments(spectrogramGridMatrix, color, q3, 2*effectiveTicks); + } + + tickList = &m_frequencyScale.getTickList(); + { + GLfloat *q3 = m_q3TickFrequency.m_array; + int effectiveTicks = 0; + + for (int i= 0; i < tickList->count(); i++) + { + tick = &(*tickList)[i]; + + if (tick->major) + { + if (tick->textSize > 0) + { + float x = tick->pos / m_frequencyScale.getSize(); + q3[4*effectiveTicks] = x; + q3[4*effectiveTicks+1] = -0.0; + q3[4*effectiveTicks+2] = x; + q3[4*effectiveTicks+3] = 1.0; + effectiveTicks++; + } + } + } + + QVector4D color(1.0f, 1.0f, 1.0f, (float) m_displayGridIntensity / 100.0f); + m_glShaderSimple.drawSegments(spectrogramGridMatrix, color, q3, 2*effectiveTicks); + } + { + GLfloat *q3 = m_q3TickFrequency.m_array; + int effectiveTicks = 0; + + for (int i= 0; i < tickList->count(); i++) + { + tick = &(*tickList)[i]; + + if (tick->major) + { + if (tick->textSize > 0) + { + float x = tick->pos / m_frequencyScale.getSize(); + q3[6*effectiveTicks] = x; + q3[6*effectiveTicks+1] = 1.0; + q3[6*effectiveTicks+2] = 0.0; + q3[6*effectiveTicks+3] = x; + q3[6*effectiveTicks+4] = 1.0; + q3[6*effectiveTicks+5] = 1.0; + effectiveTicks++; + } + } + } + + QVector4D color(1.0f, 1.0f, 1.0f, (float) m_displayGridIntensity / 100.0f); + m_glShaderSimple.drawSegments(spectrogramGridMatrix, color, q3, 2*effectiveTicks, 3); + } + + glFunctions->glViewport(0, 0, width(), height()); + } + // paint histogram grid if ((m_displayHistogram || m_displayMaxHold || m_displayCurrent) && (m_displayGrid)) { @@ -1566,7 +1904,7 @@ void GLSpectrum::applyChanges() m_rightMargin = fm.horizontalAdvance("000"); // displays both histogram and waterfall - if (m_displayWaterfall && (m_displayHistogram | m_displayMaxHold | m_displayCurrent)) + if ((m_displayWaterfall || m_display3DSpectrogram) && (m_displayHistogram | m_displayMaxHold | m_displayCurrent)) { m_waterfallHeight = height() * m_waterfallShare - 1; @@ -1611,24 +1949,9 @@ void GLSpectrum::applyChanges() m_timeScale.setRange(Unit::Time, 0, 1); } - m_powerScale.setSize(m_histogramHeight); - - if (m_linear) - { - Real referenceLevel = m_useCalibration ? m_referenceLevel * m_calibrationGain : m_referenceLevel; - m_powerScale.setRange(Unit::Scientific, 0.0f, referenceLevel); - } - else - { - Real referenceLevel = m_useCalibration ? m_referenceLevel + m_calibrationShiftdB : m_referenceLevel; - m_powerScale.setRange(Unit::Decibel, referenceLevel - m_powerRange, referenceLevel); - } - m_leftMargin = m_timeScale.getScaleWidth(); - if (m_powerScale.getScaleWidth() > m_leftMargin) { - m_leftMargin = m_powerScale.getScaleWidth(); - } + setPowerScale(m_histogramHeight); m_leftMargin += 2 * M; @@ -1688,8 +2011,8 @@ void GLSpectrum::applyChanges() -2.0f ); } - // displays waterfall only - else if (m_displayWaterfall) + // displays waterfall/3D spectrogram only + else if (m_displayWaterfall || m_display3DSpectrogram) { m_histogramHeight = 0; histogramTop = 0; @@ -1725,6 +2048,9 @@ void GLSpectrum::applyChanges() } m_leftMargin = m_timeScale.getScaleWidth(); + + setPowerScale((height() - m_topMargin - m_bottomMargin) / 2.0); + m_leftMargin += 2 * M; setFrequencyScale(); @@ -1772,10 +2098,10 @@ void GLSpectrum::applyChanges() m_waterfallHeight = 0; m_histogramHeight = height() - m_topMargin - m_frequencyScaleHeight; - m_powerScale.setSize(m_histogramHeight); - Real referenceLevel = m_useCalibration ? m_referenceLevel + m_calibrationShiftdB : m_referenceLevel; - m_powerScale.setRange(Unit::Decibel, referenceLevel - m_powerRange, referenceLevel); - m_leftMargin = m_powerScale.getScaleWidth(); + m_leftMargin = 0; + + setPowerScale(m_histogramHeight); + m_leftMargin += 2 * M; setFrequencyScale(); @@ -1830,6 +2156,9 @@ void GLSpectrum::applyChanges() m_waterfallHeight = 0; } + m_glShaderSpectrogram.setScaleX(((width() - m_leftMargin - m_rightMargin) / (float)m_waterfallHeight)); + m_glShaderSpectrogram.setScaleZ((m_histogramHeight != 0 ? m_histogramHeight : m_waterfallHeight / 4) / (float)(width() - m_leftMargin - m_rightMargin)); + // bounding boxes m_frequencyScaleRect = QRect( 0, @@ -1876,6 +2205,13 @@ void GLSpectrum::applyChanges() ); } + m_glShaderSpectrogram.setAspectRatio((width() - m_leftMargin - m_rightMargin) / (float)m_waterfallHeight); + + m_3DSpectrogramBottom = m_bottomMargin; + if (!m_invertedWaterfall) { + m_3DSpectrogramBottom += m_histogramHeight + m_frequencyScaleHeight + 1; + } + // channel overlays int64_t centerFrequency; int frequencySpan; @@ -2034,7 +2370,7 @@ void GLSpectrum::applyChanges() // prepare left scales (time and power) { m_leftMarginPixmap = QPixmap(m_leftMargin - 1, height()); - m_leftMarginPixmap.fill(Qt::black); + m_leftMarginPixmap.fill(Qt::transparent); { QPainter painter(&m_leftMarginPixmap); painter.setPen(QColor(0xf0, 0xf0, 0xff)); @@ -2066,7 +2402,7 @@ void GLSpectrum::applyChanges() m_glShaderLeftScale.initTexture(m_leftMarginPixmap.toImage()); } // prepare frequency scale - if (m_displayWaterfall || m_displayHistogram || m_displayMaxHold || m_displayCurrent){ + if (m_displayWaterfall || m_display3DSpectrogram || m_displayHistogram || m_displayMaxHold || m_displayCurrent) { m_frequencyPixmap = QPixmap(width(), m_frequencyScaleHeight); m_frequencyPixmap.fill(Qt::transparent); { @@ -2135,6 +2471,55 @@ void GLSpectrum::applyChanges() m_glShaderFrequencyScale.initTexture(m_frequencyPixmap.toImage()); } + // prepare left scale for spectrogram (time) + { + m_spectrogramTimePixmap = QPixmap(m_leftMargin - 1, fm.ascent() + m_waterfallHeight); + m_spectrogramTimePixmap.fill(Qt::transparent); + { + QPainter painter(&m_spectrogramTimePixmap); + painter.setPen(QColor(0xf0, 0xf0, 0xff)); + painter.setFont(font()); + const ScaleEngine::TickList* tickList; + const ScaleEngine::Tick* tick; + if (m_display3DSpectrogram) { + tickList = &m_timeScale.getTickList(); + for (int i = 0; i < tickList->count(); i++) { + tick = &(*tickList)[i]; + if (tick->major) { + if (tick->textSize > 0) + painter.drawText(QPointF(m_leftMargin - M - tick->textSize, fm.height() + tick->textPos), tick->text); + } + } + } + } + + m_glShaderSpectrogramTimeScale.initTexture(m_spectrogramTimePixmap.toImage()); + } + // prepare vertical scale for spectrogram (power) + { + int h = m_histogramHeight != 0 ? m_histogramHeight : m_waterfallHeight / 4; + m_spectrogramPowerPixmap = QPixmap(m_leftMargin - 1, m_topMargin + h); + m_spectrogramPowerPixmap.fill(Qt::transparent); + { + QPainter painter(&m_spectrogramPowerPixmap); + painter.setPen(QColor(0xf0, 0xf0, 0xff)); + painter.setFont(font()); + const ScaleEngine::TickList* tickList; + const ScaleEngine::Tick* tick; + if (m_display3DSpectrogram) { + tickList = &m_powerScale.getTickList(); + for (int i = 0; i < tickList->count(); i++) { + tick = &(*tickList)[i]; + if (tick->major) { + if (tick->textSize > 0) + painter.drawText(QPointF(m_leftMargin - M - tick->textSize, m_topMargin + h - tick->textPos - 1), tick->text); + } + } + } + } + + m_glShaderSpectrogramPowerScale.initTexture(m_spectrogramPowerPixmap.toImage()); + } // Top info line m_glInfoBoxMatrix.setToIdentity(); @@ -2188,7 +2573,18 @@ void GLSpectrum::applyChanges() m_waterfallBuffer->fill(qRgb(0x00, 0x00, 0x00)); m_glShaderWaterfall.initTexture(*m_waterfallBuffer); m_waterfallBufferPos = 0; + + if (m_3DSpectrogramBuffer) { + delete m_3DSpectrogramBuffer; + } + + m_3DSpectrogramBuffer = new QImage(m_nbBins, m_waterfallHeight, QImage::Format_Grayscale8); + + m_3DSpectrogramBuffer->fill(qRgb(0x00, 0x00, 0x00)); + m_glShaderSpectrogram.initTexture(*m_3DSpectrogramBuffer); + m_3DSpectrogramBufferPos = 0; } + m_glShaderSpectrogram.initColorMapTexture(m_3DSpectrogramColorMap); if (fftSizeChanged) { @@ -2218,11 +2614,13 @@ void GLSpectrum::applyChanges() { m_waterfallTextureHeight = m_waterfallHeight; m_waterfallTexturePos = 0; + m_3DSpectrogramTextureHeight = m_waterfallHeight; + m_3DSpectrogramTexturePos = 0; } m_q3TickTime.allocate(4*m_timeScale.getTickList().count()); m_q3TickFrequency.allocate(4*m_frequencyScale.getTickList().count()); - m_q3TickPower.allocate(4*m_powerScale.getTickList().count()); + m_q3TickPower.allocate(6*m_powerScale.getTickList().count()); // 6 as we need 3d points for 3D spectrogram updateHistogramMarkers(); updateWaterfallMarkers(); updateSortedAnnotationMarkers(); @@ -2461,6 +2859,37 @@ void GLSpectrum::updateCalibrationPoints() void GLSpectrum::mouseMoveEvent(QMouseEvent* event) { + if (m_rotate3DSpectrogram) + { + // Rotate 3D Spectrogram + QPointF delta = m_mousePrevLocalPos - event->localPos(); + m_mousePrevLocalPos = event->localPos(); + m_glShaderSpectrogram.rotateZ(-delta.x()/2.0f); + m_glShaderSpectrogram.rotateX(-delta.y()/2.0f); + repaint(); // Force repaint in case acquisition is stopped + return; + } + if (m_pan3DSpectrogram) + { + // Pan 3D Spectrogram + QPointF delta = m_mousePrevLocalPos - event->localPos(); + m_mousePrevLocalPos = event->localPos(); + m_glShaderSpectrogram.translateX(-delta.x()/2.0f/500.0f); + m_glShaderSpectrogram.translateY(delta.y()/2.0f/500.0f); + repaint(); // Force repaint in case acquisition is stopped + return; + } + + if (m_scaleZ3DSpectrogram) + { + // Scale 3D Spectrogram in Z dimension + QPointF delta = m_mousePrevLocalPos - event->localPos(); + m_mousePrevLocalPos = event->localPos(); + m_glShaderSpectrogram.userScaleZ(1.0+(float)delta.y()/20.0); + repaint(); // Force repaint in case acquisition is stopped + return; + } + if (m_displayWaterfall || m_displayHistogram || m_displayMaxHold || m_displayCurrent) { if (m_frequencyScaleRect.contains(event->pos())) @@ -2573,6 +3002,20 @@ void GLSpectrum::mousePressEvent(QMouseEvent* event) { const QPointF& ep = event->localPos(); + if ((event->button() == Qt::MiddleButton) && m_display3DSpectrogram && pointInWaterfallOrSpectrogram(ep)) + { + m_pan3DSpectrogram = true; + m_mousePrevLocalPos = ep; + return; + } + + if ((event->button() == Qt::RightButton) && m_display3DSpectrogram && pointInWaterfallOrSpectrogram(ep)) + { + m_scaleZ3DSpectrogram = true; + m_mousePrevLocalPos = ep; + return; + } + if (event->button() == Qt::RightButton) { QPointF pHis = ep; @@ -2681,7 +3124,7 @@ void GLSpectrum::mousePressEvent(QMouseEvent* event) frequency = m_frequencyScale.getRangeMin() + pWat.x()*m_frequencyScale.getRange(); float time = m_timeScale.getRangeMin() + pWat.y()*m_timeScale.getRange(); - if ((pWat.x() >= 0) && (pWat.x() <= 1) && (pWat.y() >= 0) && (pWat.y() <= 1)) + if ((pWat.x() >= 0) && (pWat.x() <= 1) && (pWat.y() >= 0) && (pWat.y() <= 1) && !m_display3DSpectrogram) { if (m_waterfallMarkers.size() < SpectrumWaterfallMarker::m_maxNbOfMarkers) { @@ -2727,6 +3170,16 @@ void GLSpectrum::mousePressEvent(QMouseEvent* event) { frequencyPan(event); } + else if (m_display3DSpectrogram) + { + // Detect click and drag to rotate 3D spectrogram + if (pointInWaterfallOrSpectrogram(ep)) + { + m_rotate3DSpectrogram = true; + m_mousePrevLocalPos = ep; + return; + } + } if ((m_markersDisplay == SpectrumSettings::MarkersDisplayAnnotations) && (ep.y() <= m_histogramRect.top()*height() + m_annotationMarkerHeight + 2.0f)) @@ -2794,6 +3247,9 @@ void GLSpectrum::mousePressEvent(QMouseEvent* event) void GLSpectrum::mouseReleaseEvent(QMouseEvent*) { + m_pan3DSpectrogram = false; + m_rotate3DSpectrogram = false; + m_scaleZ3DSpectrogram = false; if (m_cursorState == CSSplitterMoving) { releaseMouse(); @@ -2808,12 +3264,32 @@ void GLSpectrum::mouseReleaseEvent(QMouseEvent*) void GLSpectrum::wheelEvent(QWheelEvent *event) { - if (event->modifiers() & Qt::ShiftModifier) { - channelMarkerMove(event, 100); - } else if (event->modifiers() & Qt::ControlModifier) { - channelMarkerMove(event, 10); - } else { - channelMarkerMove(event, 1); +#if QT_VERSION >= QT_VERSION_CHECK(5, 14, 0) + const QPointF& ep = event->position(); +#else + const QPointF& ep = event->pos(); +#endif + if (pointInWaterfallOrSpectrogram(ep)) + { + // Scale 3D spectrogram when mouse wheel moved + // Some mice use delta in steps of 120 for 15 degrees + // for one step of mouse wheel + // Other mice/trackpads use smaller values + int delta = event->angleDelta().y(); + if (delta != 0) { + m_glShaderSpectrogram.verticalAngle(-5.0*delta/120.0); + } + repaint(); // Force repaint in case acquisition is stopped + } + else + { + if (event->modifiers() & Qt::ShiftModifier) { + channelMarkerMove(event, 100); + } else if (event->modifiers() & Qt::ControlModifier) { + channelMarkerMove(event, 10); + } else { + channelMarkerMove(event, 1); + } } } @@ -2973,6 +3449,26 @@ void GLSpectrum::setFrequencyScale() m_frequencyScale.setMakeOpposite(m_lsbDisplay); } +void GLSpectrum::setPowerScale(int height) +{ + m_powerScale.setSize(height); + + if (m_linear) + { + Real referenceLevel = m_useCalibration ? m_referenceLevel * m_calibrationGain : m_referenceLevel; + m_powerScale.setRange(Unit::Scientific, 0.0f, referenceLevel); + } + else + { + Real referenceLevel = m_useCalibration ? m_referenceLevel + m_calibrationShiftdB : m_referenceLevel; + m_powerScale.setRange(Unit::Decibel, referenceLevel - m_powerRange, referenceLevel); + } + + if (m_powerScale.getScaleWidth() > m_leftMargin) { + m_leftMargin = m_powerScale.getScaleWidth(); + } +} + void GLSpectrum::getFrequencyZoom(int64_t& centerFrequency, int& frequencySpan) { frequencySpan = (m_frequencyZoomFactor == 1) ? @@ -3033,6 +3529,17 @@ void GLSpectrum::channelMarkerMove(QWheelEvent *event, int mul) zoom(event); } +// Return if specified point is within the bounds of the waterfall / 3D spectrogram screen area +bool GLSpectrum::pointInWaterfallOrSpectrogram(const QPointF &point) const +{ + // m_waterfallRect is normalised to [0,1] + QPointF pWat = point; + pWat.rx() = (point.x()/width() - m_waterfallRect.left()) / m_waterfallRect.width(); + pWat.ry() = (point.y()/height() - m_waterfallRect.top()) / m_waterfallRect.height(); + + return (pWat.x() >= 0) && (pWat.x() <= 1) && (pWat.y() >= 0) && (pWat.y() <= 1); +} + void GLSpectrum::enterEvent(QEvent* event) { m_mouseInside = true; @@ -3109,6 +3616,9 @@ void GLSpectrum::cleanup() m_glShaderWaterfall.cleanup(); m_glShaderTextOverlay.cleanup(); m_glShaderInfo.cleanup(); + m_glShaderSpectrogram.cleanup(); + m_glShaderSpectrogramTimeScale.cleanup(); + m_glShaderSpectrogramPowerScale.cleanup(); //doneCurrent(); } @@ -3268,3 +3778,88 @@ void GLSpectrum::formatTextInfo(QString& info) info.append(tr("SP:%1 ").arg(displayScaled(frequencySpan, 'f', 3, true))); } } + +bool GLSpectrum::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::KeyPress) + { + QKeyEvent *keyEvent = static_cast(event); + switch (keyEvent->key()) + { + case Qt::Key_Up: + if (keyEvent->modifiers() & Qt::ShiftModifier) { + m_glShaderSpectrogram.lightRotateX(-5.0f); + } else if (keyEvent->modifiers() & Qt::AltModifier) { + m_glShaderSpectrogram.lightTranslateY(0.05); + } else if (keyEvent->modifiers() & Qt::ControlModifier) { + m_glShaderSpectrogram.translateY(0.05); + } else { + m_glShaderSpectrogram.rotateX(-5.0f); + } + break; + case Qt::Key_Down: + if (keyEvent->modifiers() & Qt::ShiftModifier) { + m_glShaderSpectrogram.lightRotateX(5.0f); + } else if (keyEvent->modifiers() & Qt::AltModifier) { + m_glShaderSpectrogram.lightTranslateY(-0.05); + } else if (keyEvent->modifiers() & Qt::ControlModifier) { + m_glShaderSpectrogram.translateY(-0.05); + } else { + m_glShaderSpectrogram.rotateX(5.0f); + } + break; + case Qt::Key_Left: + if (keyEvent->modifiers() & Qt::ShiftModifier) { + m_glShaderSpectrogram.lightRotateZ(5.0f); + } else if (keyEvent->modifiers() & Qt::AltModifier) { + m_glShaderSpectrogram.lightTranslateX(-0.05); + } else if (keyEvent->modifiers() & Qt::ControlModifier) { + m_glShaderSpectrogram.translateX(-0.05); + } else { + m_glShaderSpectrogram.rotateZ(5.0f); + } + break; + case Qt::Key_Right: + if (keyEvent->modifiers() & Qt::ShiftModifier) { + m_glShaderSpectrogram.lightRotateZ(-5.0f); + } else if (keyEvent->modifiers() & Qt::AltModifier) { + m_glShaderSpectrogram.lightTranslateX(0.05); + } else if (keyEvent->modifiers() & Qt::ControlModifier) { + m_glShaderSpectrogram.translateX(0.05); + } else { + m_glShaderSpectrogram.rotateZ(-5.0f); + } + break; + case Qt::Key_Plus: + if (keyEvent->modifiers() & Qt::ControlModifier) { + m_glShaderSpectrogram.userScaleZ(1.1f); + } else { + m_glShaderSpectrogram.verticalAngle(-1.0f); + } + break; + case Qt::Key_Minus: + if (keyEvent->modifiers() & Qt::ControlModifier) { + m_glShaderSpectrogram.userScaleZ(0.9f); + } else { + m_glShaderSpectrogram.verticalAngle(1.0f); + } + break; + case Qt::Key_R: + m_glShaderSpectrogram.reset(); + break; + case Qt::Key_F: + // Project straight down and scale to view, so it's a bit like 2D + m_glShaderSpectrogram.reset(); + m_glShaderSpectrogram.rotateX(45.0f); + m_glShaderSpectrogram.verticalAngle(-9.0f); + m_glShaderSpectrogram.userScaleZ(0.0f); + break; + } + repaint(); // Force repaint in case acquisition is stopped + return true; + } + else + { + return QOpenGLWidget::eventFilter(object, event); + } +} diff --git a/sdrgui/gui/glspectrum.h b/sdrgui/gui/glspectrum.h index 5347b5746..2993c73ca 100644 --- a/sdrgui/gui/glspectrum.h +++ b/sdrgui/gui/glspectrum.h @@ -27,11 +27,14 @@ #include #include #include +#include #include +#include #include "gui/scaleengine.h" #include "gui/glshadersimple.h" #include "gui/glshadertextured.h" #include "dsp/glspectruminterface.h" +#include "gui/glshaderspectrogram.h" #include "dsp/spectrummarkers.h" #include "dsp/channelmarker.h" #include "dsp/spectrumsettings.h" @@ -42,6 +45,7 @@ class QOpenGLShaderProgram; class MessageQueue; class SpectrumVis; +class QOpenGLDebugLogger; class SDRGUI_API GLSpectrum : public QOpenGLWidget, public GLSpectrumInterface { Q_OBJECT @@ -140,6 +144,9 @@ public: void setDecayDivisor(int decayDivisor); void setHistoStroke(int stroke); void setDisplayWaterfall(bool display); + void setDisplay3DSpectrogram(bool display); + void set3DSpectrogramStyle(SpectrumSettings::SpectrogramStyle style); + void set3DSpectrogramColorMap(const QString &colorMap); void setSsbSpectrum(bool ssbSpectrum); void setLsbDisplay(bool lsbDisplay); void setInvertedWaterfall(bool inv); @@ -292,6 +299,21 @@ private: bool m_ssbSpectrum; bool m_lsbDisplay; + QImage* m_3DSpectrogramBuffer; + int m_3DSpectrogramBufferPos; + int m_3DSpectrogramTextureHeight; + int m_3DSpectrogramTexturePos; + bool m_display3DSpectrogram; + bool m_rotate3DSpectrogram; //!< Set when mouse is pressed in 3D spectrogram area for rotation when mouse is moved + bool m_pan3DSpectrogram; + bool m_scaleZ3DSpectrogram; + QPointF m_mousePrevLocalPos; //!< Position of the mouse for last event + int m_3DSpectrogramBottom; + QPixmap m_spectrogramTimePixmap; + QPixmap m_spectrogramPowerPixmap; + SpectrumSettings::SpectrogramStyle m_3DSpectrogramStyle; + QString m_3DSpectrogramColorMap; + QRgb m_histogramPalette[240]; QImage* m_histogramBuffer; quint8* m_histogram; //!< Spectrum phosphor matrix of FFT width and PSD height scaled to 100. values [0..239] @@ -316,6 +338,9 @@ private: GLShaderTextured m_glShaderHistogram; GLShaderTextured m_glShaderTextOverlay; GLShaderTextured m_glShaderInfo; + GLShaderSpectrogram m_glShaderSpectrogram; + GLShaderTextured m_glShaderSpectrogramTimeScale; + GLShaderTextured m_glShaderSpectrogramPowerScale; int m_matrixLoc; int m_colorLoc; bool m_useCalibration; @@ -328,8 +353,10 @@ private: IncrementalArray m_q3FFT; MessageQueue *m_messageQueueToGUI; + QOpenGLDebugLogger *m_openGLLogger; void updateWaterfall(const Real *spectrum); + void update3DSpectrogram(const Real *spectrum); void updateHistogram(const Real *spectrum); void initializeGL(); @@ -354,7 +381,9 @@ private: void resetFrequencyZoom(); void updateFFTLimits(); void setFrequencyScale(); + void setPowerScale(int height); void getFrequencyZoom(int64_t& centerFrequency, int& frequencySpan); + bool pointInWaterfallOrSpectrogram(const QPointF &point) const; void enterEvent(QEvent* event); void leaveEvent(QEvent* event); @@ -394,6 +423,8 @@ private slots: void tick(); void channelMarkerChanged(); void channelMarkerDestroyed(QObject* object); + void openGLDebug(const QOpenGLDebugMessage &debugMessage); + bool eventFilter(QObject *object, QEvent *event); }; #endif // INCLUDE_GLSPECTRUM_H diff --git a/sdrgui/gui/glspectrumgui.cpp b/sdrgui/gui/glspectrumgui.cpp index 8ac0916c8..9377acaa6 100644 --- a/sdrgui/gui/glspectrumgui.cpp +++ b/sdrgui/gui/glspectrumgui.cpp @@ -31,6 +31,7 @@ #include "gui/spectrummarkersdialog.h" #include "gui/spectrumcalibrationpointsdialog.h" #include "gui/flowlayout.h" +#include "util/colormap.h" #include "util/simpleserializer.h" #include "util/db.h" #include "ui_glspectrumgui.h" @@ -70,6 +71,9 @@ GLSpectrumGUI::GLSpectrumGUI(QWidget* parent) : ui->levelRange->setStyleSheet(levelStyle); ui->fftOverlap->setStyleSheet(levelStyle); + ui->spectrogramColorMap->addItems(ColorMap::getColorMapNames()); + ui->spectrogramColorMap->setCurrentText("Angel"); + connect(&m_messageQueue, SIGNAL(messageEnqueued()), this, SLOT(handleInputMessages())); CRightClickEnabler *wsSpectrumRightClickEnabler = new CRightClickEnabler(ui->wsSpectrum); @@ -154,6 +158,11 @@ void GLSpectrumGUI::displaySettings() ui->decayDivisor->setSliderPosition(m_settings.m_decayDivisor); ui->stroke->setSliderPosition(m_settings.m_histogramStroke); ui->waterfall->setChecked(m_settings.m_displayWaterfall); + ui->spectrogram->setChecked(m_settings.m_display3DSpectrogram); + ui->spectrogramStyle->setCurrentIndex((int) m_settings.m_3DSpectrogramStyle); + ui->spectrogramStyle->setVisible(m_settings.m_display3DSpectrogram); + ui->spectrogramColorMap->setCurrentText(m_settings.m_3DSpectrogramColorMap); + ui->spectrogramColorMap->setVisible(m_settings.m_display3DSpectrogram); ui->maxHold->setChecked(m_settings.m_displayMaxHold); ui->current->setChecked(m_settings.m_displayCurrent); ui->histogram->setChecked(m_settings.m_displayHistogram); @@ -235,6 +244,9 @@ void GLSpectrumGUI::applySettings() void GLSpectrumGUI::applySpectrumSettings() { m_glSpectrum->setDisplayWaterfall(m_settings.m_displayWaterfall); + m_glSpectrum->setDisplay3DSpectrogram(m_settings.m_display3DSpectrogram); + m_glSpectrum->set3DSpectrogramStyle(m_settings.m_3DSpectrogramStyle); + m_glSpectrum->set3DSpectrogramColorMap(m_settings.m_3DSpectrogramColorMap); m_glSpectrum->setInvertedWaterfall(m_settings.m_invertedWaterfall); m_glSpectrum->setDisplayMaxHold(m_settings.m_displayMaxHold); m_glSpectrum->setDisplayCurrent(m_settings.m_displayCurrent); @@ -451,9 +463,42 @@ void GLSpectrumGUI::on_stroke_valueChanged(int index) applySettings(); } +void GLSpectrumGUI::on_spectrogramStyle_currentIndexChanged(int index) +{ + m_settings.m_3DSpectrogramStyle = (SpectrumSettings::SpectrogramStyle)index; + applySettings(); +} + +void GLSpectrumGUI::on_spectrogramColorMap_currentIndexChanged(int index) +{ + (void) index; + m_settings.m_3DSpectrogramColorMap = ui->spectrogramColorMap->currentText(); + applySettings(); +} + void GLSpectrumGUI::on_waterfall_toggled(bool checked) { m_settings.m_displayWaterfall = checked; + if (checked) + { + blockApplySettings(true); + ui->spectrogram->setChecked(false); + blockApplySettings(false); + } + applySettings(); +} + +void GLSpectrumGUI::on_spectrogram_toggled(bool checked) +{ + m_settings.m_display3DSpectrogram = checked; + if (checked) + { + blockApplySettings(true); + ui->waterfall->setChecked(false); + blockApplySettings(false); + } + ui->spectrogramStyle->setVisible(m_settings.m_display3DSpectrogram); + ui->spectrogramColorMap->setVisible(m_settings.m_display3DSpectrogram); applySettings(); } diff --git a/sdrgui/gui/glspectrumgui.h b/sdrgui/gui/glspectrumgui.h index 4e1f7cf07..45d497bb0 100644 --- a/sdrgui/gui/glspectrumgui.h +++ b/sdrgui/gui/glspectrumgui.h @@ -96,6 +96,8 @@ private slots: void on_decay_valueChanged(int index); void on_decayDivisor_valueChanged(int index); void on_stroke_valueChanged(int index); + void on_spectrogramStyle_currentIndexChanged(int index); + void on_spectrogramColorMap_currentIndexChanged(int index); void on_gridIntensity_valueChanged(int index); void on_traceIntensity_valueChanged(int index); void on_averagingMode_currentIndexChanged(int index); @@ -105,6 +107,7 @@ private slots: void on_markers_clicked(bool checked); void on_waterfall_toggled(bool checked); + void on_spectrogram_toggled(bool checked); void on_histogram_toggled(bool checked); void on_maxHold_toggled(bool checked); void on_current_toggled(bool checked); diff --git a/sdrgui/gui/glspectrumgui.ui b/sdrgui/gui/glspectrumgui.ui index 788f65f99..12e355fa8 100644 --- a/sdrgui/gui/glspectrumgui.ui +++ b/sdrgui/gui/glspectrumgui.ui @@ -123,13 +123,13 @@ - 45 + 50 0 - 45 + 50 16777215 @@ -479,7 +479,7 @@ - Spectrum maximum FPS (NL for No Limit) + Spectrum maximum FPS 0 @@ -794,6 +794,95 @@ + + + + Display 3D spectrogram + + + 3D Spectrogram + + + + :/3dspectrogram.png:/3dspectrogram.png + + + + 16 + 16 + + + + true + + + false + + + + + + + + 80 + 0 + + + + + 80 + 16777215 + + + + 3D Spectrogram Style + + + + Points + + + + + Lines + + + + + Solid + + + + + Outline + + + + + Shaded + + + + + + + + + 70 + 0 + + + + + 80 + 16777215 + + + + 3D Spectrogram Color Map + + + diff --git a/sdrgui/gui/graphicsdialog.cpp b/sdrgui/gui/graphicsdialog.cpp new file mode 100644 index 000000000..7da623336 --- /dev/null +++ b/sdrgui/gui/graphicsdialog.cpp @@ -0,0 +1,46 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2022 Jon Beniston, M7RCE // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#include + +#include "graphicsdialog.h" +#include "ui_graphicsdialog.h" + +GraphicsDialog::GraphicsDialog(MainSettings& mainSettings, QWidget* parent) : + QDialog(parent), + ui(new Ui::GraphicsDialog), + m_mainSettings(mainSettings) +{ + ui->setupUi(this); + int samples = m_mainSettings.getMultisampling(); + if (samples == 0) { + ui->multisampling->setCurrentText("Off"); + } else { + ui->multisampling->setCurrentText(QString::number(samples)); + } +} + +GraphicsDialog::~GraphicsDialog() +{ + delete ui; +} + +void GraphicsDialog::accept() +{ + m_mainSettings.setMultisampling(ui->multisampling->currentText().toInt()); + QDialog::accept(); +} diff --git a/sdrgui/gui/graphicsdialog.h b/sdrgui/gui/graphicsdialog.h new file mode 100644 index 000000000..ffba3e4f6 --- /dev/null +++ b/sdrgui/gui/graphicsdialog.h @@ -0,0 +1,43 @@ +/////////////////////////////////////////////////////////////////////////////////// +// Copyright (C) 2022 Jon Beniston, M7RCE // +// // +// This program is free software; you can redistribute it and/or modify // +// it under the terms of the GNU General Public License as published by // +// the Free Software Foundation as version 3 of the License, or // +// (at your option) any later version. // +// // +// This program 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 V3 for more details. // +// // +// You should have received a copy of the GNU General Public License // +// along with this program. If not, see . // +/////////////////////////////////////////////////////////////////////////////////// + +#ifndef SDRGUI_GUI_GRAPHICS_H_ +#define SDRGUI_GUI_GRAPHICS_H_ + +#include +#include "settings/mainsettings.h" +#include "export.h" + +namespace Ui { + class GraphicsDialog; +} + +class SDRGUI_API GraphicsDialog : public QDialog { + Q_OBJECT +public: + explicit GraphicsDialog(MainSettings& mainSettings, QWidget* parent = 0); + ~GraphicsDialog(); + +private: + Ui::GraphicsDialog* ui; + MainSettings& m_mainSettings; + +private slots: + void accept(); +}; + +#endif /* SDRGUI_GUI_GRAPHICS_H_ */ diff --git a/sdrgui/gui/graphicsdialog.ui b/sdrgui/gui/graphicsdialog.ui new file mode 100644 index 000000000..9dc2642c2 --- /dev/null +++ b/sdrgui/gui/graphicsdialog.ui @@ -0,0 +1,128 @@ + + + GraphicsDialog + + + + 0 + 0 + 277 + 98 + + + + + Liberation Sans + 9 + + + + Graphics settings + + + + + + + + + 150 + 0 + + + + Multisampling (MSAA) + + + + + + + + 80 + 0 + + + + Number of samples to use for mulitsampling anti-aliasing (MSAA) - Requires windows to be reopened + + + + Off + + + + + 2 + + + + + 4 + + + + + 8 + + + + + + + + + + Qt::Horizontal + + + QDialogButtonBox::Cancel|QDialogButtonBox::Ok + + + true + + + + + + + buttonBox + + + + + + + buttonBox + accepted() + GraphicsDialog + accept() + + + 257 + 194 + + + 157 + 203 + + + + + buttonBox + rejected() + GraphicsDialog + reject() + + + 314 + 194 + + + 286 + 203 + + + + + diff --git a/sdrgui/gui/spectrum.md b/sdrgui/gui/spectrum.md index 7147b32be..63cdb3c41 100644 --- a/sdrgui/gui/spectrum.md +++ b/sdrgui/gui/spectrum.md @@ -315,3 +315,39 @@ Use the toggle button to switch between relative and calibrated power readings. Right click to open the [calibration management dialog](spectrumcalibration.md) +

B.5: 3D Spectrogram Controls

+ +The 3D Spectrogram controls are only visible when the 3D Spectrogram is being displayed. + +

B.5.1: Style

+ +This dropdown determines how the 3D Spectrogram data is rendered. + + - Points: The data are rendeded as points. + - Lines: The data points are connected by lines. + - Solid: The data are rendeded as a solid surface with constant illumination. + - Outline: The data are rendered as a solid surface with outlines of the polygons highlighted. + - Shaded: The data are rendeder as a solid surface with a combination of ambient and diffuse lighting. + +

B.5.2: Color Map

+ +This dropdown allows the selection of a number of pre-defined color maps that are used for rendering the 3D Spectrogram. +'Angel' is the default SDRangel color map. + +

3D Spectrogram Controls

+ +The 3D Spectrogram view can be controlled by mouse/trackpad: + + - Left button: Rotate + - Middle button: Pan + - Right button: Scale Z axis (power) + - Wheel/pinch: Zoom + +Or keyboard: + + - Arrow: Rotate + - CTRL Arrow: Pan + - '+'/'-': Zoom + - CTRL '+'/'-': Scale Z axis (power) + - 'r': Reset view to default + - 'f': Flat view (top down) diff --git a/sdrgui/mainwindow.cpp b/sdrgui/mainwindow.cpp index 1a186e990..8e0a55b95 100644 --- a/sdrgui/mainwindow.cpp +++ b/sdrgui/mainwindow.cpp @@ -56,6 +56,7 @@ #include "gui/aboutdialog.h" #include "gui/rollupwidget.h" #include "gui/audiodialog.h" +#include "gui/graphicsdialog.h" #include "gui/loggingdialog.h" #include "gui/deviceuserargsdialog.h" #include "gui/sdrangelsplash.h" @@ -1455,6 +1456,9 @@ void MainWindow::createMenuBar() QAction *audioAction = preferencesMenu->addAction("&Audio..."); audioAction->setToolTip("Audio preferences"); QObject::connect(audioAction, &QAction::triggered, this, &MainWindow::on_action_Audio_triggered); + QAction *graphicsAction = preferencesMenu->addAction("&Graphics..."); + graphicsAction->setToolTip("Graphics preferences"); + QObject::connect(graphicsAction, &QAction::triggered, this, &MainWindow::on_action_Graphics_triggered); QAction *loggingAction = preferencesMenu->addAction("&Logging..."); loggingAction->setToolTip("Logging preferences"); QObject::connect(loggingAction, &QAction::triggered, this, &MainWindow::on_action_Logging_triggered); @@ -2029,6 +2033,12 @@ void MainWindow::on_action_Audio_triggered() audioDialog.exec(); } +void MainWindow::on_action_Graphics_triggered() +{ + GraphicsDialog graphicsDialog(m_mainCore->m_settings, this); + graphicsDialog.exec(); +} + void MainWindow::on_action_Logging_triggered() { LoggingDialog loggingDialog(m_mainCore->m_settings, this); diff --git a/sdrgui/mainwindow.h b/sdrgui/mainwindow.h index 5e8261906..54625921a 100644 --- a/sdrgui/mainwindow.h +++ b/sdrgui/mainwindow.h @@ -179,6 +179,7 @@ private slots: void on_action_saveAll_triggered(); void on_action_Configurations_triggered(); void on_action_Audio_triggered(); + void on_action_Graphics_triggered(); void on_action_Logging_triggered(); void on_action_FFT_triggered(); void on_action_My_Position_triggered(); diff --git a/sdrgui/readme.md b/sdrgui/readme.md index cefd1f8af..e7cbf64e3 100644 --- a/sdrgui/readme.md +++ b/sdrgui/readme.md @@ -19,6 +19,7 @@ The menu items from left to right are: - Preferences: - _Configurations_: opens a dialog to manage instance configurations. See configurations dialog documentation [here](configurations.md) - _Audio_: opens a dialog to choose the audio output device. See the audio management documentation [here](audio.md) + - _Graphics_: opens a dialog to choose graphics options. - _Logging_: opens a dialog to choose logging options. See "Logging" paragraph next for details - _FFT_: opens a dialog to run the `fftwf-wisdom` utility with a choice of direct and possibly reverse FFT sizes. It produces a so called wisdom file `fftw-wisdom` that speeds up FFT allocations. It is created at a default location and will be used at next invocations of SDRangel. See "FFT" paragraph next for details. - _My Position_: opens a dialog to enter your station ("My Position") coordinates in decimal degrees with north latitudes positive and east longitudes positive. This is used whenever positional data is to be displayed (APRS, DPRS, ...). For it now only works with D-Star $$CRC frames. See [DSD demod plugin](../plugins/channelrx/demoddsd/readme.md) for details on how to decode Digital Voice modes. @@ -429,6 +430,20 @@ This will delete the currently selected command or if selection is a group this Use this button to activate the keyboard bindings. Note that you need to have this button selected (its background should be lit in beige/orange) for the key bindings to be effective. +

2.4: Graphics

+ +When clicking on the Graphics submenu a dialog opens for setting graphics options. + +![Main Window Graphics](../doc/img/MainWindow_graphics.png) + +

2.4.1

+ +Multisampling (MSAA) determines whether multisampling anti-aliasing is used to removed the jagged edges of lines when rendering 2D and 3D spectra. +The higher the number of samples chosen, the better quality the anti-aliasing will be, but higher values require more GPU processing and memory. + +Changing this option will only take effect when spectrum windows are recreated (not just hidden then made visible again), so in some cases it +may be necessary to restart SDRangel to see the difference. +

3: Help

3.1: Loaded plugins

diff --git a/sdrgui/resources/3dspectrogram.png b/sdrgui/resources/3dspectrogram.png new file mode 100644 index 0000000000000000000000000000000000000000..5c76e7ac7a756332be54efcc023b96cf053e5550 GIT binary patch literal 1633 zcmV-n2A=teP)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGf6951U69E94oEQKA00(qQO+^RY2@eSm zDrEIJ-~a#x<4Ht8R7gv0mP?2nRTPH5di1-ix@RUcJ(G#SF>0bAVx9|;i1D#-p+Q}W z3-N(3L=Xg5Q4m+68&?Vv7j7iF7C|wf5fcST#JuN`ah^RrJ=NXSUEN(>{?*f?2sv=6 z>8g9r`Okm;bM6@K3y(!i%zz!h>>k4LIn0K`)b77Hz9Zz9b$DeI?piN#wzSNT6&Ovy zsktQcYc5tN2j%TBJ_~*x{@wvS6Wa1;C$NIsM^6MpGX(V{ooJPjotN?KC3fXol+rC6 zE8t)dkgyV*X;(1KfE#|mMbBp_zfRRyp;5C5np)K?K@buoYXoMOpx4F3=|VRPra>=d zvbvF{(=1Z!g+!4+h0qZot7G5@d0X#X8xmm_&rcIJMj+ROv{s-EJ$;O{%02lt6d)O3 zIIEDXW7r|Xg*wz6AvLk&_}8*c)Ik6gOlRuC)6&y7S`>0EteiM2PlBgFeo{e%sHOeG z3TAh7EYTsV+yc!4Q7_4gmr*e7C=Zb|U@X_AlK?}GGYXQ>QlfN~$+cC7Rz=QDMHF3> z)|8Dtq%63u8l-iOXO2X)6?tq!C~EMX3ce@=vf@#TC*BCzqX0+zaqQj_AHN6RT-^Nr zKN}a#_el-g#$Z|gB4waBs)6z^RiRRbFaC2LTlI9v$#>wdw*Gc>R@vVWu$$VF4_`}3 zKd;ESl$BBXzO4XtootDg-v*vX^!v>{@T8uxU4k=b;d=#nU3Gj&sQPvc-ufCI{@lQN zH-~jlg^lfkf>Z?5SAdZ~0hYyCTofhHw+Hi>*>&ta7RAAfRgT8&NZ&7Mnd%cMqapS`eRqLl|MYqXurGfSbvVgYkYdjL?i!xi7DcXJPR>h7YOtb5a{DaS z(qLa~f9jJ)Ofg|_xFEU5RK=!_J)qyKI_`?$BV#>E+qV>;P193)#43vQx-RXOwSF(r zK6jMx<$H17%%R?-eFjdSluV`OD@w{zPiOC8;}b{0!T|MJ2ZQQ&fQeuCQk7J;gK ztV*FV$tplfr;~yg&y`503Tpc>L3YQ#a1qT6X=HV_WSUkD)EA+qCWcaJ3<;#BLEpq( zb{N*u3Q$!#bxG>8bMU^roL4PI=E$W2?rd(sReMaxhvHq@qPb`B-PJLSL_21~H^5DbG z?2dcj0m;r+!8c+RslZ{Niz9ByXEnCBGLcO@0{4HYrqtLqI}r!8r6FK9wMhx$xTLvX z^fa__d9(Em_qAgY1y!%Gtczw0+g)Ke+h)Uacyf1@ZMK0YiN0!-B#dP~65WSX!yh&J z&o1PdDEQo1m?T=%y&Nks6mnm*M_T%AdfMns7x5MxT?bv(C7|hQL!Ic+?$q$w9(g>% zZjGAW)%3d-czD{^>Q%U2t+Uapchannels.png channels_add.png exit_round.png + 3dspectrogram.png LiberationMono-Regular.ttf LiberationSans-Regular.ttf From c135affb6af0ce677b16c9b3a935a66ef0511536 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sat, 18 Jun 2022 13:07:10 +0100 Subject: [PATCH 02/12] Simply matrix calcs. Fix for clang --- sdrgui/gui/glshaderspectrogram.cpp | 29 ++++++++----------- sdrgui/gui/glshaderspectrogram.h | 4 +-- sdrgui/gui/glspectrum.cpp | 45 ++++++++++++++---------------- 3 files changed, 35 insertions(+), 43 deletions(-) diff --git a/sdrgui/gui/glshaderspectrogram.cpp b/sdrgui/gui/glshaderspectrogram.cpp index f6da94599..6e3938305 100644 --- a/sdrgui/gui/glshaderspectrogram.cpp +++ b/sdrgui/gui/glshaderspectrogram.cpp @@ -310,7 +310,7 @@ void GLShaderSpectrogram::subTextureMutable(int xOffset, int yOffset, int width, glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels); } -void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, float textureOffset, bool invert) +void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, const QMatrix4x4& vertexTransform, float textureOffset, bool invert) { if ((m_useImmutableStorage && !m_texture) || (!m_useImmutableStorage && !m_textureId)) { @@ -325,17 +325,6 @@ void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, program = m_programSimple; } - // Note that translation to the origin and rotation - // needs to be performed in reverse order to what you - // might normally expect - // See: https://bugreports.qt.io/browse/QTBUG-20752 - - QMatrix4x4 vertexTransform; - vertexTransform.translate(0.0f, 0.0f, -1.65f); - applyScaleRotate(vertexTransform); - vertexTransform.translate(-0.5f, -0.5f, 0.0f); - applyPerspective(vertexTransform); - float rot = invert ? 1.0 : -1.0; QMatrix4x4 textureTransform( 1.0, 0.0, 0.0, 0.0, @@ -652,14 +641,20 @@ void GLShaderSpectrogram::lightRotateZ(float degrees) m_lightRotZ += degrees; } -void GLShaderSpectrogram::applyScaleRotate(QMatrix4x4 &matrix) +void GLShaderSpectrogram::applyTransform(QMatrix4x4 &matrix) { - // As above, this is in reverse - matrix.translate(m_translateX, m_translateY, m_translateZ); - matrix.rotate(m_rotX, 1.0f, 0.0f, 0.0f); + // Note that translation to the origin and rotation + // needs to be performed in reverse order to what you + // might normally expect + // See: https://bugreports.qt.io/browse/QTBUG-20752 + matrix.translate(0.0f, 0.0f, -1.65f); // Camera position + matrix.translate(m_translateX, m_translateY, m_translateZ); // User camera position adjustment + matrix.rotate(m_rotX, 1.0f, 0.0f, 0.0f); // User rotation matrix.rotate(m_rotY, 0.0f, 1.0f, 0.0f); matrix.rotate(m_rotZ, 0.0f, 0.0f, 1.0f); - matrix.scale(m_scaleX, m_scaleY, m_scaleZ * m_userScaleZ); + matrix.scale(m_scaleX, m_scaleY, m_scaleZ * m_userScaleZ); // Scaling + matrix.translate(-0.5f, -0.5f, 0.0f); // Centre at origin for correct rotation + applyPerspective(matrix); } void GLShaderSpectrogram::applyPerspective(QMatrix4x4 &matrix) diff --git a/sdrgui/gui/glshaderspectrogram.h b/sdrgui/gui/glshaderspectrogram.h index 786208634..598b25753 100644 --- a/sdrgui/gui/glshaderspectrogram.h +++ b/sdrgui/gui/glshaderspectrogram.h @@ -40,7 +40,7 @@ public: void initColorMapTexture(const QString &colorMapName); void initTexture(const QImage& image); void subTexture(int xOffset, int yOffset, int width, int height, const void *pixels); - void drawSurface(SpectrumSettings::SpectrogramStyle style, float textureOffset, bool invert); + void drawSurface(SpectrumSettings::SpectrogramStyle style, const QMatrix4x4& vertexTransform, float textureOffset, bool invert); void cleanup(); void translateX(float distance); void translateY(float distance); @@ -61,7 +61,7 @@ public: void lightRotateX(float degrees); void lightRotateY(float degrees); void lightRotateZ(float degrees); - void applyScaleRotate(QMatrix4x4 &matrix); + void applyTransform(QMatrix4x4 &matrix); void applyPerspective(QMatrix4x4 &matrix); private: diff --git a/sdrgui/gui/glspectrum.cpp b/sdrgui/gui/glspectrum.cpp index 769450dde..35c4dd868 100644 --- a/sdrgui/gui/glspectrum.cpp +++ b/sdrgui/gui/glspectrum.cpp @@ -872,13 +872,10 @@ void GLSpectrum::paintGL() glFunctions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); QMatrix4x4 spectrogramGridMatrix; - spectrogramGridMatrix.translate(0.0f, 0.0f, -1.65f); - m_glShaderSpectrogram.applyScaleRotate(spectrogramGridMatrix); - spectrogramGridMatrix.translate(-0.5f, -0.5f, 0.0f); - m_glShaderSpectrogram.applyPerspective(spectrogramGridMatrix); if (m_display3DSpectrogram) { + m_glShaderSpectrogram.applyTransform(spectrogramGridMatrix); // paint 3D spectrogram if (m_3DSpectrogramTexturePos + m_3DSpectrogramBufferPos < m_3DSpectrogramTextureHeight) { @@ -900,7 +897,7 @@ void GLSpectrum::paintGL() // Temporarily reduce viewport to waterfall area so anything outside is clipped glFunctions->glViewport(0, m_3DSpectrogramBottom, width(), m_waterfallHeight); - m_glShaderSpectrogram.drawSurface(m_3DSpectrogramStyle, prop_y, m_invertedWaterfall); + m_glShaderSpectrogram.drawSurface(m_3DSpectrogramStyle, spectrogramGridMatrix, prop_y, m_invertedWaterfall); glFunctions->glViewport(0, 0, width(), height()); } else if (m_displayWaterfall) @@ -1168,15 +1165,15 @@ void GLSpectrum::paintGL() { glFunctions->glViewport(0, m_3DSpectrogramBottom, width(), m_waterfallHeight); { - float l = m_spectrogramTimePixmap.width() / (float) width(); - float r = m_rightMargin / (float) width(); - float h = m_frequencyPixmap.height() / (float) m_waterfallHeight; + GLfloat l = m_spectrogramTimePixmap.width() / (GLfloat) width(); + GLfloat r = m_rightMargin / (GLfloat) width(); + GLfloat h = m_frequencyPixmap.height() / (GLfloat) m_waterfallHeight; GLfloat vtx1[] = { - -l, -h, - 1+r, -h, - 1+r, 0, - -l, 0 + -l, -h, + 1.0f+r, -h, + 1.0f+r, 0.0f, + -l, 0.0f }; GLfloat tex1[] = { 0, 1, @@ -1189,14 +1186,14 @@ void GLSpectrum::paintGL() } { - float w = m_spectrogramTimePixmap.width() / (float) width(); - float h = (m_bottomMargin/2) / (float) m_waterfallHeight; // m_bottomMargin is fm.ascent + GLfloat w = m_spectrogramTimePixmap.width() / (GLfloat) width(); + GLfloat h = (m_bottomMargin/2) / (GLfloat) m_waterfallHeight; // m_bottomMargin is fm.ascent GLfloat vtx1[] = { - -w, 0.0-h, - 0, 0.0-h, - 0, 1.0+h, - -w, 1.0+h + -w, 0.0f-h, + 0.0f, 0.0f-h, + 0.0f, 1.0f+h, + -w, 1.0f+h }; GLfloat tex1[] = { 0, 1, @@ -1209,14 +1206,14 @@ void GLSpectrum::paintGL() } { - float w = m_spectrogramPowerPixmap.width() / (float) width(); - float h = m_topMargin / (float) m_spectrogramPowerPixmap.height(); + GLfloat w = m_spectrogramPowerPixmap.width() / (GLfloat) width(); + GLfloat h = m_topMargin / (GLfloat) m_spectrogramPowerPixmap.height(); GLfloat vtx1[] = { - -w, 1.0, 0.0, - 0, 1.0, 0.0, - 0, 1.0, 1.0+h, - -w, 1.0, 1.0+h, + -w, 1.0f, 0.0f, + 0.0f, 1.0f, 0.0f, + 0.0f, 1.0f, 1.0f+h, + -w, 1.0f, 1.0f+h, }; GLfloat tex1[] = { 0, 1, From e13e919012b82505d1d9673d0bdcccfffd5ea915 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sat, 18 Jun 2022 23:40:25 +0100 Subject: [PATCH 03/12] Add OpenGL shaders using OpenGL 3.3 syntax for MacOS which doesn't support version 2 syntax wth 4.2 context --- sdrgui/gui/glscope.cpp | 19 ++-- sdrgui/gui/glshadercolors.cpp | 53 ++++++++--- sdrgui/gui/glshadercolors.h | 4 +- sdrgui/gui/glshadersimple.cpp | 49 ++++++++--- sdrgui/gui/glshadersimple.h | 4 +- sdrgui/gui/glshaderspectrogram.cpp | 136 ++++++++++++++++++++--------- sdrgui/gui/glshaderspectrogram.h | 6 +- sdrgui/gui/glshadertextured.cpp | 56 +++++++++--- sdrgui/gui/glshadertextured.h | 4 +- sdrgui/gui/glspectrum.cpp | 26 +++--- sdrgui/gui/spectrum.md | 2 +- 11 files changed, 263 insertions(+), 96 deletions(-) diff --git a/sdrgui/gui/glscope.cpp b/sdrgui/gui/glscope.cpp index ae2840026..c72ff25a8 100644 --- a/sdrgui/gui/glscope.cpp +++ b/sdrgui/gui/glscope.cpp @@ -156,6 +156,7 @@ void GLScope::newTraces(std::vector *traces, int traceIndex, std::vecto void GLScope::initializeGL() { QOpenGLContext *glCurrentContext = QOpenGLContext::currentContext(); + float openGLVersion = 0.0f; if (glCurrentContext) { @@ -165,6 +166,8 @@ void GLScope::initializeGL() << " major: " << (QOpenGLContext::currentContext()->format()).majorVersion() << " minor: " << (QOpenGLContext::currentContext()->format()).minorVersion() << " ES: " << (QOpenGLContext::currentContext()->isOpenGLES() ? "yes" : "no"); + openGLVersion = (QOpenGLContext::currentContext()->format()).majorVersion() + + ((QOpenGLContext::currentContext()->format()).minorVersion() / 10.0); } else { @@ -205,14 +208,14 @@ void GLScope::initializeGL() glFunctions->initializeOpenGLFunctions(); //glDisable(GL_DEPTH_TEST); - m_glShaderSimple.initializeGL(); - m_glShaderColors.initializeGL(); - m_glShaderLeft1Scale.initializeGL(); - m_glShaderBottom1Scale.initializeGL(); - m_glShaderLeft2Scale.initializeGL(); - m_glShaderBottom2Scale.initializeGL(); - m_glShaderPowerOverlay.initializeGL(); - m_glShaderTextOverlay.initializeGL(); + m_glShaderSimple.initializeGL(openGLVersion); + m_glShaderColors.initializeGL(openGLVersion); + m_glShaderLeft1Scale.initializeGL(openGLVersion); + m_glShaderBottom1Scale.initializeGL(openGLVersion); + m_glShaderLeft2Scale.initializeGL(openGLVersion); + m_glShaderBottom2Scale.initializeGL(openGLVersion); + m_glShaderPowerOverlay.initializeGL(openGLVersion); + m_glShaderTextOverlay.initializeGL(openGLVersion); } void GLScope::resizeGL(int width, int height) diff --git a/sdrgui/gui/glshadercolors.cpp b/sdrgui/gui/glshadercolors.cpp index 3bf3e47ff..52d4985b9 100644 --- a/sdrgui/gui/glshadercolors.cpp +++ b/sdrgui/gui/glshadercolors.cpp @@ -36,17 +36,28 @@ GLShaderColors::~GLShaderColors() cleanup(); } -void GLShaderColors::initializeGL() +void GLShaderColors::initializeGL(float openGLVersion) { m_program = new QOpenGLShaderProgram; - if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceSimple)) { - qDebug() << "GLShaderColors::initializeGL: error in vertex shader: " << m_program->log(); - } - - if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceColored)) { - qDebug() << "GLShaderColors::initializeGL: error in fragment shader: " << m_program->log(); - } + if (openGLVersion >= 3.3) + { + if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceSimple)) { + qDebug() << "GLShaderColors::initializeGL: error in vertex shader: " << m_program->log(); + } + if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceColored)) { + qDebug() << "GLShaderColors::initializeGL: error in fragment shader: " << m_program->log(); + } + } + else + { + if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceSimple2)) { + qDebug() << "GLShaderColors::initializeGL: error in vertex shader: " << m_program->log(); + } + if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceColored2)) { + qDebug() << "GLShaderColors::initializeGL: error in fragment shader: " << m_program->log(); + } + } m_program->bindAttributeLocation("vertex", 0); m_program->bindAttributeLocation("v_color", 1); @@ -118,7 +129,7 @@ void GLShaderColors::cleanup() } } -const QString GLShaderColors::m_vertexShaderSourceSimple = QString( +const QString GLShaderColors::m_vertexShaderSourceSimple2 = QString( "uniform highp mat4 uMatrix;\n" "attribute highp vec4 vertex;\n" "attribute vec3 v_color;\n" @@ -129,10 +140,32 @@ const QString GLShaderColors::m_vertexShaderSourceSimple = QString( "}\n" ); -const QString GLShaderColors::m_fragmentShaderSourceColored = QString( +const QString GLShaderColors::m_vertexShaderSourceSimple = QString( + "#version 330\n" + "uniform highp mat4 uMatrix;\n" + "in highp vec4 vertex;\n" + "in vec3 v_color;\n" + "out vec3 f_color;\n" + "void main() {\n" + " gl_Position = uMatrix * vertex;\n" + " f_color = v_color;\n" + "}\n" + ); + +const QString GLShaderColors::m_fragmentShaderSourceColored2 = QString( "uniform mediump float uAlpha;\n" "varying vec3 f_color;\n" "void main() {\n" " gl_FragColor = vec4(f_color.r, f_color.g, f_color.b, uAlpha);\n" "}\n" ); + +const QString GLShaderColors::m_fragmentShaderSourceColored = QString( + "#version 330\n" + "uniform mediump float uAlpha;\n" + "in vec3 f_color;\n" + "out vec4 fragColor;\n" + "void main() {\n" + " fragColor = vec4(f_color.r, f_color.g, f_color.b, uAlpha);\n" + "}\n" + ); diff --git a/sdrgui/gui/glshadercolors.h b/sdrgui/gui/glshadercolors.h index 67d45cee0..dbe93fb4b 100644 --- a/sdrgui/gui/glshadercolors.h +++ b/sdrgui/gui/glshadercolors.h @@ -37,7 +37,7 @@ public: GLShaderColors(); ~GLShaderColors(); - void initializeGL(); + void initializeGL(float openGLVersion); void drawPoints(const QMatrix4x4& transformMatrix, GLfloat *vertices, GLfloat *colors, GLfloat alpha, int nbVertices); void drawPolyline(const QMatrix4x4& transformMatrix, GLfloat *vertices, GLfloat *colors, GLfloat alpha, int nbVertices); void drawSegments(const QMatrix4x4& transformMatrix, GLfloat *vertices, GLfloat *colors, GLfloat alpha, int nbVertices); @@ -51,7 +51,9 @@ private: QOpenGLShaderProgram *m_program; int m_matrixLoc; int m_alphaLoc; + static const QString m_vertexShaderSourceSimple2; static const QString m_vertexShaderSourceSimple; + static const QString m_fragmentShaderSourceColored2; static const QString m_fragmentShaderSourceColored; }; diff --git a/sdrgui/gui/glshadersimple.cpp b/sdrgui/gui/glshadersimple.cpp index a5c425c24..eefaa9656 100644 --- a/sdrgui/gui/glshadersimple.cpp +++ b/sdrgui/gui/glshadersimple.cpp @@ -36,17 +36,28 @@ GLShaderSimple::~GLShaderSimple() cleanup(); } -void GLShaderSimple::initializeGL() +void GLShaderSimple::initializeGL(float openGLVersion) { m_program = new QOpenGLShaderProgram; - if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceSimple)) { - qDebug() << "GLShaderSimple::initializeGL: error in vertex shader: " << m_program->log(); - } - - if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceColored)) { - qDebug() << "GLShaderSimple::initializeGL: error in fragment shader: " << m_program->log(); - } + if (openGLVersion >= 3.3) + { + if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceSimple)) { + qDebug() << "GLShaderSimple::initializeGL: error in vertex shader: " << m_program->log(); + } + if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceColored)) { + qDebug() << "GLShaderSimple::initializeGL: error in fragment shader: " << m_program->log(); + } + } + else + { + if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceSimple2)) { + qDebug() << "GLShaderSimple::initializeGL: error in vertex shader: " << m_program->log(); + } + if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceColored2)) { + qDebug() << "GLShaderSimple::initializeGL: error in fragment shader: " << m_program->log(); + } + } m_program->bindAttributeLocation("vertex", 0); @@ -110,7 +121,7 @@ void GLShaderSimple::cleanup() } } -const QString GLShaderSimple::m_vertexShaderSourceSimple = QString( +const QString GLShaderSimple::m_vertexShaderSourceSimple2 = QString( "uniform highp mat4 uMatrix;\n" "attribute highp vec4 vertex;\n" "void main() {\n" @@ -118,9 +129,27 @@ const QString GLShaderSimple::m_vertexShaderSourceSimple = QString( "}\n" ); -const QString GLShaderSimple::m_fragmentShaderSourceColored = QString( +const QString GLShaderSimple::m_vertexShaderSourceSimple = QString( + "#version 330\n" + "uniform highp mat4 uMatrix;\n" + "in highp vec4 vertex;\n" + "void main() {\n" + " gl_Position = uMatrix * vertex;\n" + "}\n" + ); + +const QString GLShaderSimple::m_fragmentShaderSourceColored2 = QString( "uniform mediump vec4 uColour;\n" "void main() {\n" " gl_FragColor = uColour;\n" "}\n" ); + +const QString GLShaderSimple::m_fragmentShaderSourceColored = QString( + "#version 330\n" + "out vec4 fragColor;\n" + "uniform mediump vec4 uColour;\n" + "void main() {\n" + " fragColor = uColour;\n" + "}\n" + ); diff --git a/sdrgui/gui/glshadersimple.h b/sdrgui/gui/glshadersimple.h index f52cdd519..02da9bc22 100644 --- a/sdrgui/gui/glshadersimple.h +++ b/sdrgui/gui/glshadersimple.h @@ -34,7 +34,7 @@ public: GLShaderSimple(); ~GLShaderSimple(); - void initializeGL(); + void initializeGL(float openGLVersion); void drawPoints(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents=2); void drawPolyline(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents=2); void drawSegments(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents=2); @@ -48,7 +48,9 @@ private: QOpenGLShaderProgram *m_program; int m_matrixLoc; int m_colorLoc; + static const QString m_vertexShaderSourceSimple2; static const QString m_vertexShaderSourceSimple; + static const QString m_fragmentShaderSourceColored2; static const QString m_fragmentShaderSourceColored; }; diff --git a/sdrgui/gui/glshaderspectrogram.cpp b/sdrgui/gui/glshaderspectrogram.cpp index 6e3938305..b33d65f2d 100644 --- a/sdrgui/gui/glshaderspectrogram.cpp +++ b/sdrgui/gui/glshaderspectrogram.cpp @@ -38,7 +38,7 @@ GLShaderSpectrogram::GLShaderSpectrogram() : m_programForLocs(nullptr), m_textureTransformLoc(0), m_vertexTransformLoc(0), - m_textureLoc(0), + m_dataTextureLoc(0), m_limitLoc(0), m_brightnessLoc(0), m_colorMapLoc(0), @@ -75,35 +75,51 @@ GLShaderSpectrogram::~GLShaderSpectrogram() cleanup(); } -void GLShaderSpectrogram::initializeGL() +void GLShaderSpectrogram::initializeGL(float openGLVersion) { initializeOpenGLFunctions(); m_useImmutableStorage = useImmutableStorage(); qDebug() << "GLShaderSpectrogram::initializeGL: m_useImmutableStorage: " << m_useImmutableStorage; - m_programShaded = new QOpenGLShaderProgram; - if (!m_programShaded->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShader)) { - qDebug() << "GLShaderSpectrogram::initializeGL: error in vertex shader: " << m_programShaded->log(); - } - if (!m_programShaded->addShaderFromSourceCode(QOpenGLShader::Geometry, m_geometryShader)) { - qDebug() << "GLShaderSpectrogram::initializeGL: error in geometry shader: " << m_programShaded->log(); - } - if (!m_programShaded->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderShaded)) { - qDebug() << "GLShaderSpectrogram::initializeGL: error in fragment shader: " << m_programShaded->log(); - } - if (!m_programShaded->link()) { - qDebug() << "GLShaderSpectrogram::initializeGL: error linking shader: " << m_programShaded->log(); - } + if (openGLVersion >= 3.3) + { + m_programShaded = new QOpenGLShaderProgram; + if (!m_programShaded->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShader)) { + qDebug() << "GLShaderSpectrogram::initializeGL: error in vertex shader: " << m_programShaded->log(); + } + if (!m_programShaded->addShaderFromSourceCode(QOpenGLShader::Geometry, m_geometryShader)) { + qDebug() << "GLShaderSpectrogram::initializeGL: error in geometry shader: " << m_programShaded->log(); + } + if (!m_programShaded->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderShaded)) { + qDebug() << "GLShaderSpectrogram::initializeGL: error in fragment shader: " << m_programShaded->log(); + } + if (!m_programShaded->link()) { + qDebug() << "GLShaderSpectrogram::initializeGL: error linking shader: " << m_programShaded->log(); + } - m_programSimple = new QOpenGLShaderProgram; - if (!m_programSimple->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShader)) { - qDebug() << "GLShaderSpectrogram::initializeGL: error in vertex shader: " << m_programSimple->log(); + m_programSimple = new QOpenGLShaderProgram; + if (!m_programSimple->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShader)) { + qDebug() << "GLShaderSpectrogram::initializeGL: error in vertex shader: " << m_programSimple->log(); + } + if (!m_programSimple->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSimple)) { + qDebug() << "GLShaderSpectrogram::initializeGL: error in fragment shader: " << m_programSimple->log(); + } + if (!m_programSimple->link()) { + qDebug() << "GLShaderSpectrogram::initializeGL: error linking shader: " << m_programSimple->log(); + } } - if (!m_programSimple->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSimple)) { - qDebug() << "GLShaderSpectrogram::initializeGL: error in fragment shader: " << m_programSimple->log(); - } - if (!m_programSimple->link()) { - qDebug() << "GLShaderSpectrogram::initializeGL: error linking shader: " << m_programSimple->log(); + else + { + m_programSimple = new QOpenGLShaderProgram; + if (!m_programSimple->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShader2)) { + qDebug() << "GLShaderSpectrogram::initializeGL: error in vertex shader: " << m_programSimple->log(); + } + if (!m_programSimple->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSimple2)) { + qDebug() << "GLShaderSpectrogram::initializeGL: error in fragment shader: " << m_programSimple->log(); + } + if (!m_programSimple->link()) { + qDebug() << "GLShaderSpectrogram::initializeGL: error linking shader: " << m_programSimple->log(); + } } } @@ -324,6 +340,9 @@ void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, } else { program = m_programSimple; } + if (!program) { + return; + } float rot = invert ? 1.0 : -1.0; QMatrix4x4 textureTransform( @@ -339,7 +358,7 @@ void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, { m_textureTransformLoc = program->uniformLocation("textureTransform"); m_vertexTransformLoc = program->uniformLocation("vertexTransform"); - m_textureLoc = program->uniformLocation("texture"); + m_dataTextureLoc = program->uniformLocation("dataTexture"); m_limitLoc = program->uniformLocation("limit"); m_brightnessLoc = program->uniformLocation("brightness"); m_colorMapLoc = program->uniformLocation("colorMap"); @@ -366,7 +385,7 @@ void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, glActiveTexture(GL_TEXTURE0); } - program->setUniformValue(m_textureLoc, 0); // set uniform to texture unit? + program->setUniformValue(m_dataTextureLoc, 0); // set uniform to texture unit? program->setUniformValue(m_colorMapLoc, 1); program->setUniformValue(m_limitLoc, 1.5f*1.0f/(float)(m_gridElements)); @@ -664,18 +683,36 @@ void GLShaderSpectrogram::applyPerspective(QMatrix4x4 &matrix) // The clamp is to prevent old data affecting new data (And vice versa), // which can happen where the texture repeats - might be a better way to do it -const QString GLShaderSpectrogram::m_vertexShader = QString( +const QString GLShaderSpectrogram::m_vertexShader2 = QString( "attribute vec2 coord2d;\n" "varying vec4 coord;\n" "varying float lightDistance;\n" "uniform mat4 textureTransform;\n" "uniform mat4 vertexTransform;\n" - "uniform sampler2D texture;\n" + "uniform sampler2D dataTexture;\n" "uniform float limit;\n" "uniform vec3 lightPos;\n" "void main(void) {\n" " coord = textureTransform * vec4(clamp(coord2d, limit, 1.0-limit), 0, 1);\n" - " coord.z = (texture2D(texture, coord.xy).r);\n" + " coord.z = (texture2D(dataTexture, coord.xy).r);\n" + " gl_Position = vertexTransform * vec4(coord2d, coord.z, 1);\n" + " lightDistance = length(lightPos - gl_Position.xyz);\n" + "}\n" + ); + +const QString GLShaderSpectrogram::m_vertexShader = QString( + "#version 330\n" + "in vec2 coord2d;\n" + "out vec4 coord;\n" + "out float lightDistance;\n" + "uniform mat4 textureTransform;\n" + "uniform mat4 vertexTransform;\n" + "uniform sampler2D dataTexture;\n" + "uniform float limit;\n" + "uniform vec3 lightPos;\n" + "void main(void) {\n" + " coord = textureTransform * vec4(clamp(coord2d, limit, 1.0-limit), 0, 1);\n" + " coord.z = (texture(dataTexture, coord.xy).r);\n" " gl_Position = vertexTransform * vec4(coord2d, coord.z, 1);\n" " lightDistance = length(lightPos - gl_Position.xyz);\n" "}\n" @@ -709,9 +746,11 @@ const QString GLShaderSpectrogram::m_geometryShader = QString( ); const QString GLShaderSpectrogram::m_fragmentShaderShaded = QString( - "varying vec4 coord2;\n" - "varying vec3 normal;\n" - "varying float lightDistance2;\n" + "#version 330\n" + "in vec4 coord2;\n" + "in vec3 normal;\n" + "in float lightDistance2;\n" + "out vec4 fragColor;\n" "uniform sampler1D colorMap;\n" "uniform vec3 lightDir;\n" "void main(void) {\n" @@ -722,20 +761,20 @@ const QString GLShaderSpectrogram::m_fragmentShaderShaded = QString( " factor = 0.5;\n" " float ambient = 0.4;\n" " vec3 color;\n" - " color.r = texture1D(colorMap, coord2.z).r;\n" - " color.g = texture1D(colorMap, coord2.z).g;\n" - " color.b = texture1D(colorMap, coord2.z).b;\n" + " color.r = texture(colorMap, coord2.z).r;\n" + " color.g = texture(colorMap, coord2.z).g;\n" + " color.b = texture(colorMap, coord2.z).b;\n" " float cosTheta = max(0.0, dot(normal, lightDir));\n" " float d2 = max(1.0, lightDistance2*lightDistance2);\n" " vec3 relection = (ambient * color + color * cosTheta / d2) * factor;\n" - " gl_FragColor[0] = relection.r;\n" - " gl_FragColor[1] = relection.g;\n" - " gl_FragColor[2] = relection.b;\n" - " gl_FragColor[3] = 1.0;\n" + " fragColor[0] = relection.r;\n" + " fragColor[1] = relection.g;\n" + " fragColor[2] = relection.b;\n" + " fragColor[3] = 1.0;\n" "}\n" ); -const QString GLShaderSpectrogram::m_fragmentShaderSimple = QString( +const QString GLShaderSpectrogram::m_fragmentShaderSimple2 = QString( "varying vec4 coord;\n" "uniform float brightness;\n" "uniform sampler1D colorMap;\n" @@ -751,3 +790,22 @@ const QString GLShaderSpectrogram::m_fragmentShaderSimple = QString( " gl_FragColor[3] = 1.0;\n" "}\n" ); + +const QString GLShaderSpectrogram::m_fragmentShaderSimple = QString( + "#version 330\n" + "in vec4 coord;\n" + "out vec4 fragColor;\n" + "uniform float brightness;\n" + "uniform sampler1D colorMap;\n" + "void main(void) {\n" + " float factor;\n" + " if (gl_FrontFacing)\n" + " factor = 1.0;\n" + " else\n" + " factor = 0.5;\n" + " fragColor[0] = texture(colorMap, coord.z).r * brightness * factor;\n" + " fragColor[1] = texture(colorMap, coord.z).g * brightness * factor;\n" + " fragColor[2] = texture(colorMap, coord.z).b * brightness * factor;\n" + " fragColor[3] = 1.0;\n" + "}\n" + ); diff --git a/sdrgui/gui/glshaderspectrogram.h b/sdrgui/gui/glshaderspectrogram.h index 598b25753..bfcfa6b29 100644 --- a/sdrgui/gui/glshaderspectrogram.h +++ b/sdrgui/gui/glshaderspectrogram.h @@ -36,7 +36,7 @@ public: GLShaderSpectrogram(); ~GLShaderSpectrogram(); - void initializeGL(); + void initializeGL(float openGLVersion); void initColorMapTexture(const QString &colorMapName); void initTexture(const QImage& image); void subTexture(int xOffset, int yOffset, int width, int height, const void *pixels); @@ -85,7 +85,7 @@ private: QOpenGLShaderProgram *m_programForLocs; // Which program the locations are for int m_textureTransformLoc; int m_vertexTransformLoc; - int m_textureLoc; + int m_dataTextureLoc; int m_limitLoc; int m_brightnessLoc; int m_colorMapLoc; @@ -93,9 +93,11 @@ private: int m_lightPosLoc; bool m_useImmutableStorage; + static const QString m_vertexShader2; static const QString m_vertexShader; static const QString m_geometryShader; static const QString m_fragmentShaderShaded; + static const QString m_fragmentShaderSimple2; static const QString m_fragmentShaderSimple; QOpenGLBuffer m_vertexBuf; diff --git a/sdrgui/gui/glshadertextured.cpp b/sdrgui/gui/glshadertextured.cpp index fdd20198e..3d7fb5084 100644 --- a/sdrgui/gui/glshadertextured.cpp +++ b/sdrgui/gui/glshadertextured.cpp @@ -40,21 +40,31 @@ GLShaderTextured::~GLShaderTextured() cleanup(); } -void GLShaderTextured::initializeGL() +void GLShaderTextured::initializeGL(float openGLVersion) { initializeOpenGLFunctions(); m_useImmutableStorage = useImmutableStorage(); qDebug() << "GLShaderTextured::initializeGL: m_useImmutableStorage: " << m_useImmutableStorage; - m_program = new QOpenGLShaderProgram; - - if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceTextured)) { - qDebug() << "GLShaderTextured::initializeGL: error in vertex shader: " << m_program->log(); - } - - if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceTextured)) { - qDebug() << "GLShaderTextured::initializeGL: error in fragment shader: " << m_program->log(); - } + m_program = new QOpenGLShaderProgram; + if (openGLVersion >= 3.3f) + { + if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceTextured)) { + qDebug() << "GLShaderTextured::initializeGL: error in vertex shader: " << m_program->log(); + } + if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceTextured)) { + qDebug() << "GLShaderTextured::initializeGL: error in fragment shader: " << m_program->log(); + } + } + else + { + if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceTextured2)) { + qDebug() << "GLShaderTextured::initializeGL: error in vertex shader: " << m_program->log(); + } + if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceTextured2)) { + qDebug() << "GLShaderTextured::initializeGL: error in fragment shader: " << m_program->log(); + } + } m_program->bindAttributeLocation("vertex", 0); m_program->bindAttributeLocation("texCoord", 1); @@ -248,7 +258,7 @@ bool GLShaderTextured::useImmutableStorage() return false; } -const QString GLShaderTextured::m_vertexShaderSourceTextured = QString( +const QString GLShaderTextured::m_vertexShaderSourceTextured2 = QString( "uniform highp mat4 uMatrix;\n" "attribute highp vec4 vertex;\n" "attribute highp vec2 texCoord;\n" @@ -259,10 +269,32 @@ const QString GLShaderTextured::m_vertexShaderSourceTextured = QString( "}\n" ); -const QString GLShaderTextured::m_fragmentShaderSourceTextured = QString( +const QString GLShaderTextured::m_vertexShaderSourceTextured = QString( + "#version 330\n" + "uniform highp mat4 uMatrix;\n" + "in highp vec4 vertex;\n" + "in highp vec2 texCoord;\n" + "out mediump vec2 texCoordVar;\n" + "void main() {\n" + " gl_Position = uMatrix * vertex;\n" + " texCoordVar = texCoord;\n" + "}\n" + ); + +const QString GLShaderTextured::m_fragmentShaderSourceTextured2 = QString( "uniform lowp sampler2D uTexture;\n" "varying mediump vec2 texCoordVar;\n" "void main() {\n" " gl_FragColor = texture2D(uTexture, texCoordVar);\n" "}\n" ); + +const QString GLShaderTextured::m_fragmentShaderSourceTextured = QString( + "#version 330\n" + "uniform lowp sampler2D uTexture;\n" + "in mediump vec2 texCoordVar;\n" + "out vec4 fragColor;\n" + "void main() {\n" + " fragColor = texture(uTexture, texCoordVar);\n" + "}\n" + ); diff --git a/sdrgui/gui/glshadertextured.h b/sdrgui/gui/glshadertextured.h index a938a159b..a9151d2d3 100644 --- a/sdrgui/gui/glshadertextured.h +++ b/sdrgui/gui/glshadertextured.h @@ -38,7 +38,7 @@ public: GLShaderTextured(); ~GLShaderTextured(); - void initializeGL(); + void initializeGL(float openGLVersion); void initTexture(const QImage& image, QOpenGLTexture::WrapMode wrapMode = QOpenGLTexture::Repeat); void subTexture(int xOffset, int yOffset, int width, int height, const void *pixels); void drawSurface(const QMatrix4x4& transformMatrix, GLfloat* textureCoords, GLfloat *vertices, int nbVertices, int nbComponents=2); @@ -59,7 +59,9 @@ private: int m_matrixLoc; int m_textureLoc; bool m_useImmutableStorage; + static const QString m_vertexShaderSourceTextured2; static const QString m_vertexShaderSourceTextured; + static const QString m_fragmentShaderSourceTextured2; static const QString m_fragmentShaderSourceTextured; }; diff --git a/sdrgui/gui/glspectrum.cpp b/sdrgui/gui/glspectrum.cpp index 35c4dd868..414249539 100644 --- a/sdrgui/gui/glspectrum.cpp +++ b/sdrgui/gui/glspectrum.cpp @@ -766,14 +766,18 @@ void GLSpectrum::updateHistogram(const Real *spectrum) void GLSpectrum::initializeGL() { QOpenGLContext *glCurrentContext = QOpenGLContext::currentContext(); + float openGLVersion = 0.0f; if (glCurrentContext) { - if (QOpenGLContext::currentContext()->isValid()) { + if (QOpenGLContext::currentContext()->isValid()) + { qDebug() << "GLSpectrum::initializeGL: context:" << " major: " << (QOpenGLContext::currentContext()->format()).majorVersion() << " minor: " << (QOpenGLContext::currentContext()->format()).minorVersion() << " ES: " << (QOpenGLContext::currentContext()->isOpenGLES() ? "yes" : "no"); + openGLVersion = (QOpenGLContext::currentContext()->format()).majorVersion() + + ((QOpenGLContext::currentContext()->format()).minorVersion() / 10.0); } else { qDebug() << "GLSpectrum::initializeGL: current context is invalid"; @@ -812,16 +816,16 @@ void GLSpectrum::initializeGL() glFunctions->initializeOpenGLFunctions(); //glDisable(GL_DEPTH_TEST); - m_glShaderSimple.initializeGL(); - m_glShaderLeftScale.initializeGL(); - m_glShaderFrequencyScale.initializeGL(); - m_glShaderWaterfall.initializeGL(); - m_glShaderHistogram.initializeGL(); - m_glShaderTextOverlay.initializeGL(); - m_glShaderInfo.initializeGL(); - m_glShaderSpectrogram.initializeGL(); - m_glShaderSpectrogramTimeScale.initializeGL(); - m_glShaderSpectrogramPowerScale.initializeGL(); + m_glShaderSimple.initializeGL(openGLVersion); + m_glShaderLeftScale.initializeGL(openGLVersion); + m_glShaderFrequencyScale.initializeGL(openGLVersion); + m_glShaderWaterfall.initializeGL(openGLVersion); + m_glShaderHistogram.initializeGL(openGLVersion); + m_glShaderTextOverlay.initializeGL(openGLVersion); + m_glShaderInfo.initializeGL(openGLVersion); + m_glShaderSpectrogram.initializeGL(openGLVersion); + m_glShaderSpectrogramTimeScale.initializeGL(openGLVersion); + m_glShaderSpectrogramPowerScale.initializeGL(openGLVersion); } void GLSpectrum::openGLDebug(const QOpenGLDebugMessage &debugMessage) diff --git a/sdrgui/gui/spectrum.md b/sdrgui/gui/spectrum.md index 63cdb3c41..e64b56d65 100644 --- a/sdrgui/gui/spectrum.md +++ b/sdrgui/gui/spectrum.md @@ -327,7 +327,7 @@ This dropdown determines how the 3D Spectrogram data is rendered. - Lines: The data points are connected by lines. - Solid: The data are rendeded as a solid surface with constant illumination. - Outline: The data are rendered as a solid surface with outlines of the polygons highlighted. - - Shaded: The data are rendeder as a solid surface with a combination of ambient and diffuse lighting. + - Shaded: The data are rendeder as a solid surface with a combination of ambient and diffuse lighting. This requires OpenGL 3.3 or greater.

B.5.2: Color Map

From e31880fc660e6291252b17cc02130b21c0f312a2 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sun, 19 Jun 2022 00:11:46 +0100 Subject: [PATCH 04/12] Use integers for OpenGL version --- sdrgui/gui/glscope.cpp | 23 ++++++++++++----------- sdrgui/gui/glshadercolors.cpp | 4 ++-- sdrgui/gui/glshadercolors.h | 2 +- sdrgui/gui/glshadersimple.cpp | 4 ++-- sdrgui/gui/glshadersimple.h | 2 +- sdrgui/gui/glshaderspectrogram.cpp | 4 ++-- sdrgui/gui/glshaderspectrogram.h | 2 +- sdrgui/gui/glshadertextured.cpp | 4 ++-- sdrgui/gui/glshadertextured.h | 2 +- sdrgui/gui/glspectrum.cpp | 27 ++++++++++++++------------- 10 files changed, 38 insertions(+), 36 deletions(-) diff --git a/sdrgui/gui/glscope.cpp b/sdrgui/gui/glscope.cpp index c72ff25a8..e449710bd 100644 --- a/sdrgui/gui/glscope.cpp +++ b/sdrgui/gui/glscope.cpp @@ -156,7 +156,8 @@ void GLScope::newTraces(std::vector *traces, int traceIndex, std::vecto void GLScope::initializeGL() { QOpenGLContext *glCurrentContext = QOpenGLContext::currentContext(); - float openGLVersion = 0.0f; + int majorVersion = 0; + int minorVersion = 0; if (glCurrentContext) { @@ -166,8 +167,8 @@ void GLScope::initializeGL() << " major: " << (QOpenGLContext::currentContext()->format()).majorVersion() << " minor: " << (QOpenGLContext::currentContext()->format()).minorVersion() << " ES: " << (QOpenGLContext::currentContext()->isOpenGLES() ? "yes" : "no"); - openGLVersion = (QOpenGLContext::currentContext()->format()).majorVersion() - + ((QOpenGLContext::currentContext()->format()).minorVersion() / 10.0); + majorVersion = (QOpenGLContext::currentContext()->format()).majorVersion(); + minorVersion = (QOpenGLContext::currentContext()->format()).minorVersion(); } else { @@ -208,14 +209,14 @@ void GLScope::initializeGL() glFunctions->initializeOpenGLFunctions(); //glDisable(GL_DEPTH_TEST); - m_glShaderSimple.initializeGL(openGLVersion); - m_glShaderColors.initializeGL(openGLVersion); - m_glShaderLeft1Scale.initializeGL(openGLVersion); - m_glShaderBottom1Scale.initializeGL(openGLVersion); - m_glShaderLeft2Scale.initializeGL(openGLVersion); - m_glShaderBottom2Scale.initializeGL(openGLVersion); - m_glShaderPowerOverlay.initializeGL(openGLVersion); - m_glShaderTextOverlay.initializeGL(openGLVersion); + m_glShaderSimple.initializeGL(majorVersion, minorVersion); + m_glShaderColors.initializeGL(majorVersion, minorVersion); + m_glShaderLeft1Scale.initializeGL(majorVersion, minorVersion); + m_glShaderBottom1Scale.initializeGL(majorVersion, minorVersion); + m_glShaderLeft2Scale.initializeGL(majorVersion, minorVersion); + m_glShaderBottom2Scale.initializeGL(majorVersion, minorVersion); + m_glShaderPowerOverlay.initializeGL(majorVersion, minorVersion); + m_glShaderTextOverlay.initializeGL(majorVersion, minorVersion); } void GLScope::resizeGL(int width, int height) diff --git a/sdrgui/gui/glshadercolors.cpp b/sdrgui/gui/glshadercolors.cpp index 52d4985b9..d005ad94c 100644 --- a/sdrgui/gui/glshadercolors.cpp +++ b/sdrgui/gui/glshadercolors.cpp @@ -36,11 +36,11 @@ GLShaderColors::~GLShaderColors() cleanup(); } -void GLShaderColors::initializeGL(float openGLVersion) +void GLShaderColors::initializeGL(int majorVersion, int minorVersion) { m_program = new QOpenGLShaderProgram; - if (openGLVersion >= 3.3) + if ((majorVersion > 3) || ((majorVersion == 3) && (minorVersion >= 3))) { if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceSimple)) { qDebug() << "GLShaderColors::initializeGL: error in vertex shader: " << m_program->log(); diff --git a/sdrgui/gui/glshadercolors.h b/sdrgui/gui/glshadercolors.h index dbe93fb4b..cf5f9ca38 100644 --- a/sdrgui/gui/glshadercolors.h +++ b/sdrgui/gui/glshadercolors.h @@ -37,7 +37,7 @@ public: GLShaderColors(); ~GLShaderColors(); - void initializeGL(float openGLVersion); + void initializeGL(int majorVersion, int minorVersion); void drawPoints(const QMatrix4x4& transformMatrix, GLfloat *vertices, GLfloat *colors, GLfloat alpha, int nbVertices); void drawPolyline(const QMatrix4x4& transformMatrix, GLfloat *vertices, GLfloat *colors, GLfloat alpha, int nbVertices); void drawSegments(const QMatrix4x4& transformMatrix, GLfloat *vertices, GLfloat *colors, GLfloat alpha, int nbVertices); diff --git a/sdrgui/gui/glshadersimple.cpp b/sdrgui/gui/glshadersimple.cpp index eefaa9656..58dc1bdec 100644 --- a/sdrgui/gui/glshadersimple.cpp +++ b/sdrgui/gui/glshadersimple.cpp @@ -36,11 +36,11 @@ GLShaderSimple::~GLShaderSimple() cleanup(); } -void GLShaderSimple::initializeGL(float openGLVersion) +void GLShaderSimple::initializeGL(int majorVersion, int minorVersion) { m_program = new QOpenGLShaderProgram; - if (openGLVersion >= 3.3) + if ((majorVersion > 3) || ((majorVersion == 3) && (minorVersion >= 3))) { if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceSimple)) { qDebug() << "GLShaderSimple::initializeGL: error in vertex shader: " << m_program->log(); diff --git a/sdrgui/gui/glshadersimple.h b/sdrgui/gui/glshadersimple.h index 02da9bc22..9768129b3 100644 --- a/sdrgui/gui/glshadersimple.h +++ b/sdrgui/gui/glshadersimple.h @@ -34,7 +34,7 @@ public: GLShaderSimple(); ~GLShaderSimple(); - void initializeGL(float openGLVersion); + void initializeGL(int majorVersion, int minorVersion); void drawPoints(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents=2); void drawPolyline(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents=2); void drawSegments(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents=2); diff --git a/sdrgui/gui/glshaderspectrogram.cpp b/sdrgui/gui/glshaderspectrogram.cpp index b33d65f2d..7955c21f6 100644 --- a/sdrgui/gui/glshaderspectrogram.cpp +++ b/sdrgui/gui/glshaderspectrogram.cpp @@ -75,13 +75,13 @@ GLShaderSpectrogram::~GLShaderSpectrogram() cleanup(); } -void GLShaderSpectrogram::initializeGL(float openGLVersion) +void GLShaderSpectrogram::initializeGL(int majorVersion, int minorVersion) { initializeOpenGLFunctions(); m_useImmutableStorage = useImmutableStorage(); qDebug() << "GLShaderSpectrogram::initializeGL: m_useImmutableStorage: " << m_useImmutableStorage; - if (openGLVersion >= 3.3) + if ((majorVersion > 3) || ((majorVersion == 3) && (minorVersion >= 3))) { m_programShaded = new QOpenGLShaderProgram; if (!m_programShaded->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShader)) { diff --git a/sdrgui/gui/glshaderspectrogram.h b/sdrgui/gui/glshaderspectrogram.h index bfcfa6b29..b33eb963f 100644 --- a/sdrgui/gui/glshaderspectrogram.h +++ b/sdrgui/gui/glshaderspectrogram.h @@ -36,7 +36,7 @@ public: GLShaderSpectrogram(); ~GLShaderSpectrogram(); - void initializeGL(float openGLVersion); + void initializeGL(int majorVersion, int minorVersion); void initColorMapTexture(const QString &colorMapName); void initTexture(const QImage& image); void subTexture(int xOffset, int yOffset, int width, int height, const void *pixels); diff --git a/sdrgui/gui/glshadertextured.cpp b/sdrgui/gui/glshadertextured.cpp index 3d7fb5084..76168b4e4 100644 --- a/sdrgui/gui/glshadertextured.cpp +++ b/sdrgui/gui/glshadertextured.cpp @@ -40,14 +40,14 @@ GLShaderTextured::~GLShaderTextured() cleanup(); } -void GLShaderTextured::initializeGL(float openGLVersion) +void GLShaderTextured::initializeGL(int majorVersion, int minorVersion) { initializeOpenGLFunctions(); m_useImmutableStorage = useImmutableStorage(); qDebug() << "GLShaderTextured::initializeGL: m_useImmutableStorage: " << m_useImmutableStorage; m_program = new QOpenGLShaderProgram; - if (openGLVersion >= 3.3f) + if ((majorVersion > 3) || ((majorVersion == 3) && (minorVersion >= 3))) { if (!m_program->addShaderFromSourceCode(QOpenGLShader::Vertex, m_vertexShaderSourceTextured)) { qDebug() << "GLShaderTextured::initializeGL: error in vertex shader: " << m_program->log(); diff --git a/sdrgui/gui/glshadertextured.h b/sdrgui/gui/glshadertextured.h index a9151d2d3..868a26f1d 100644 --- a/sdrgui/gui/glshadertextured.h +++ b/sdrgui/gui/glshadertextured.h @@ -38,7 +38,7 @@ public: GLShaderTextured(); ~GLShaderTextured(); - void initializeGL(float openGLVersion); + void initializeGL(int majorVersion, int minorVersion); void initTexture(const QImage& image, QOpenGLTexture::WrapMode wrapMode = QOpenGLTexture::Repeat); void subTexture(int xOffset, int yOffset, int width, int height, const void *pixels); void drawSurface(const QMatrix4x4& transformMatrix, GLfloat* textureCoords, GLfloat *vertices, int nbVertices, int nbComponents=2); diff --git a/sdrgui/gui/glspectrum.cpp b/sdrgui/gui/glspectrum.cpp index 414249539..f7d7fafe9 100644 --- a/sdrgui/gui/glspectrum.cpp +++ b/sdrgui/gui/glspectrum.cpp @@ -766,7 +766,8 @@ void GLSpectrum::updateHistogram(const Real *spectrum) void GLSpectrum::initializeGL() { QOpenGLContext *glCurrentContext = QOpenGLContext::currentContext(); - float openGLVersion = 0.0f; + int majorVersion = 0; + int minorVersion = 0; if (glCurrentContext) { @@ -776,8 +777,8 @@ void GLSpectrum::initializeGL() << " major: " << (QOpenGLContext::currentContext()->format()).majorVersion() << " minor: " << (QOpenGLContext::currentContext()->format()).minorVersion() << " ES: " << (QOpenGLContext::currentContext()->isOpenGLES() ? "yes" : "no"); - openGLVersion = (QOpenGLContext::currentContext()->format()).majorVersion() - + ((QOpenGLContext::currentContext()->format()).minorVersion() / 10.0); + majorVersion = (QOpenGLContext::currentContext()->format()).majorVersion(); + minorVersion = (QOpenGLContext::currentContext()->format()).minorVersion(); } else { qDebug() << "GLSpectrum::initializeGL: current context is invalid"; @@ -816,16 +817,16 @@ void GLSpectrum::initializeGL() glFunctions->initializeOpenGLFunctions(); //glDisable(GL_DEPTH_TEST); - m_glShaderSimple.initializeGL(openGLVersion); - m_glShaderLeftScale.initializeGL(openGLVersion); - m_glShaderFrequencyScale.initializeGL(openGLVersion); - m_glShaderWaterfall.initializeGL(openGLVersion); - m_glShaderHistogram.initializeGL(openGLVersion); - m_glShaderTextOverlay.initializeGL(openGLVersion); - m_glShaderInfo.initializeGL(openGLVersion); - m_glShaderSpectrogram.initializeGL(openGLVersion); - m_glShaderSpectrogramTimeScale.initializeGL(openGLVersion); - m_glShaderSpectrogramPowerScale.initializeGL(openGLVersion); + m_glShaderSimple.initializeGL(majorVersion, minorVersion); + m_glShaderLeftScale.initializeGL(majorVersion, minorVersion); + m_glShaderFrequencyScale.initializeGL(majorVersion, minorVersion); + m_glShaderWaterfall.initializeGL(majorVersion, minorVersion); + m_glShaderHistogram.initializeGL(majorVersion, minorVersion); + m_glShaderTextOverlay.initializeGL(majorVersion, minorVersion); + m_glShaderInfo.initializeGL(majorVersion, minorVersion); + m_glShaderSpectrogram.initializeGL(majorVersion, minorVersion); + m_glShaderSpectrogramTimeScale.initializeGL(majorVersion, minorVersion); + m_glShaderSpectrogramPowerScale.initializeGL(majorVersion, minorVersion); } void GLSpectrum::openGLDebug(const QOpenGLDebugMessage &debugMessage) From 74d61855e49c63429dcf476a8b63bba16e63da12 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sun, 19 Jun 2022 11:22:46 +0100 Subject: [PATCH 05/12] Use VAOs for OpenGL 3 CoreProfile --- sdrgui/gui/glshadersimple.cpp | 51 ++++++++-- sdrgui/gui/glshadersimple.h | 5 + sdrgui/gui/glshaderspectrogram.cpp | 152 ++++++++++++++++++----------- sdrgui/gui/glshaderspectrogram.h | 8 +- sdrgui/gui/glshadertextured.cpp | 91 ++++++++++++----- sdrgui/gui/glshadertextured.h | 7 ++ 6 files changed, 224 insertions(+), 90 deletions(-) diff --git a/sdrgui/gui/glshadersimple.cpp b/sdrgui/gui/glshadersimple.cpp index 58dc1bdec..ef6b7244a 100644 --- a/sdrgui/gui/glshadersimple.cpp +++ b/sdrgui/gui/glshadersimple.cpp @@ -26,7 +26,10 @@ #include "gui/glshadersimple.h" GLShaderSimple::GLShaderSimple() : - m_program(0), + m_program(nullptr), + m_vao(nullptr), + m_verticesBuf(nullptr), + m_vertexLoc(0), m_matrixLoc(0), m_colorLoc(0) { } @@ -66,8 +69,19 @@ void GLShaderSimple::initializeGL(int majorVersion, int minorVersion) } m_program->bind(); + m_vertexLoc = m_program->attributeLocation("vertex"); m_matrixLoc = m_program->uniformLocation("uMatrix"); m_colorLoc = m_program->uniformLocation("uColour"); + if (m_vao) + { + m_vao = new QOpenGLVertexArrayObject(); + m_vao->create(); + m_vao->bind(); + m_verticesBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + m_verticesBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw); + m_verticesBuf->create(); + m_vao->release(); + } m_program->release(); } @@ -102,23 +116,42 @@ void GLShaderSimple::draw(unsigned int mode, const QMatrix4x4& transformMatrix, m_program->bind(); m_program->setUniformValue(m_matrixLoc, transformMatrix); m_program->setUniformValue(m_colorLoc, color); + if (m_vao) + { + m_vao->bind(); + + m_verticesBuf->bind(); + m_verticesBuf->allocate(vertices, nbVertices * nbComponents * sizeof(GL_FLOAT)); + m_program->enableAttributeArray(m_vertexLoc); + m_program->setAttributeBuffer(m_vertexLoc, GL_FLOAT, 0, nbComponents); + } + else + { + f->glEnableVertexAttribArray(m_vertexLoc); // vertex + f->glVertexAttribPointer(m_vertexLoc, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); + } + f->glEnable(GL_BLEND); f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); f->glLineWidth(1.0f); - f->glEnableVertexAttribArray(0); // vertex - f->glVertexAttribPointer(0, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); f->glDrawArrays(mode, 0, nbVertices); - f->glDisableVertexAttribArray(0); + + if (m_vao) { + m_vao->release(); + } else { + f->glDisableVertexAttribArray(m_vertexLoc); + } m_program->release(); } void GLShaderSimple::cleanup() { - if (QOpenGLContext::currentContext() && m_program) - { - delete m_program; - m_program = nullptr; - } + delete m_program; + m_program = nullptr; + delete m_vao; + m_vao = nullptr; + delete m_verticesBuf; + m_verticesBuf = nullptr; } const QString GLShaderSimple::m_vertexShaderSourceSimple2 = QString( diff --git a/sdrgui/gui/glshadersimple.h b/sdrgui/gui/glshadersimple.h index 9768129b3..5e261087d 100644 --- a/sdrgui/gui/glshadersimple.h +++ b/sdrgui/gui/glshadersimple.h @@ -21,6 +21,8 @@ #include #include +#include +#include #include "export.h" @@ -46,6 +48,9 @@ private: void draw(unsigned int mode, const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents); QOpenGLShaderProgram *m_program; + QOpenGLVertexArrayObject *m_vao; + QOpenGLBuffer *m_verticesBuf; + int m_vertexLoc; int m_matrixLoc; int m_colorLoc; static const QString m_vertexShaderSourceSimple2; diff --git a/sdrgui/gui/glshaderspectrogram.cpp b/sdrgui/gui/glshaderspectrogram.cpp index 7955c21f6..2b3a702f3 100644 --- a/sdrgui/gui/glshaderspectrogram.cpp +++ b/sdrgui/gui/glshaderspectrogram.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -36,6 +37,7 @@ GLShaderSpectrogram::GLShaderSpectrogram() : m_colorMapTexture(nullptr), m_colorMapTextureId(0), m_programForLocs(nullptr), + m_coord2dLoc(0), m_textureTransformLoc(0), m_vertexTransformLoc(0), m_dataTextureLoc(0), @@ -45,9 +47,10 @@ GLShaderSpectrogram::GLShaderSpectrogram() : m_lightDirLoc(0), m_lightPosLoc(0), m_useImmutableStorage(true), - m_vertexBuf(QOpenGLBuffer::VertexBuffer), - m_index0Buf(QOpenGLBuffer::IndexBuffer), - m_index1Buf(QOpenGLBuffer::IndexBuffer), + m_vao(nullptr), + m_vertexBuf(nullptr), + m_index0Buf(nullptr), + m_index1Buf(nullptr), m_translateX(0.0), m_translateY(0.0), m_translateZ(0.0), @@ -107,6 +110,10 @@ void GLShaderSpectrogram::initializeGL(int majorVersion, int minorVersion) if (!m_programSimple->link()) { qDebug() << "GLShaderSpectrogram::initializeGL: error linking shader: " << m_programSimple->log(); } + + m_vao = new QOpenGLVertexArrayObject(); + m_vao->create(); + m_vao->bind(); } else { @@ -121,6 +128,20 @@ void GLShaderSpectrogram::initializeGL(int majorVersion, int minorVersion) qDebug() << "GLShaderSpectrogram::initializeGL: error linking shader: " << m_programSimple->log(); } } + + m_vertexBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + m_vertexBuf->setUsagePattern(QOpenGLBuffer::StaticDraw); + m_vertexBuf->create(); + m_index0Buf = new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer); + m_index0Buf->setUsagePattern(QOpenGLBuffer::StaticDraw); + m_index0Buf->create(); + m_index1Buf = new QOpenGLBuffer(QOpenGLBuffer::IndexBuffer); + m_index1Buf->setUsagePattern(QOpenGLBuffer::StaticDraw); + m_index1Buf->create(); + + if (m_vao) { + m_vao->release(); + } } void GLShaderSpectrogram::initGrid(int elements) @@ -141,17 +162,12 @@ void GLShaderSpectrogram::initGrid(int elements) } } - m_vertexBuf.setUsagePattern(QOpenGLBuffer::StaticDraw); - m_vertexBuf.create(); + if (m_vao) { + m_vao->bind(); + } - m_index0Buf.setUsagePattern(QOpenGLBuffer::StaticDraw); - m_index0Buf.create(); - - m_index1Buf.setUsagePattern(QOpenGLBuffer::StaticDraw); - m_index1Buf.create(); - - m_vertexBuf.bind(); - m_vertexBuf.allocate(&vertices[0], vertices.size() * sizeof(QVector2D)); + m_vertexBuf->bind(); + m_vertexBuf->allocate(&vertices[0], vertices.size() * sizeof(QVector2D)); // Create an array of indices into the vertex array that traces both horizontal and vertical lines std::vector indices(m_gridElements * m_gridElements * 6); @@ -171,8 +187,8 @@ void GLShaderSpectrogram::initGrid(int elements) } } - m_index0Buf.bind(); - m_index0Buf.allocate(&indices[0], m_gridElements * (e1) * 4 * sizeof(GLuint)); + m_index0Buf->bind(); + m_index0Buf->allocate(&indices[0], m_gridElements * (e1) * 4 * sizeof(GLuint)); // Create another array of indices that describes all the triangles needed to create a completely filled surface i = 0; @@ -189,12 +205,19 @@ void GLShaderSpectrogram::initGrid(int elements) } } - m_index1Buf.bind(); - m_index1Buf.allocate(&indices[0], indices.size() * sizeof(GLuint)); + m_index1Buf->bind(); + m_index1Buf->allocate(&indices[0], indices.size() * sizeof(GLuint)); - QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); - f->glBindBuffer(GL_ARRAY_BUFFER, 0); - f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + if (m_vao) + { + m_vao->release(); + } + else + { + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + f->glBindBuffer(GL_ARRAY_BUFFER, 0); + f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } } void GLShaderSpectrogram::initColorMapTexture(const QString &colorMapName) @@ -356,6 +379,7 @@ void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, if (program != m_programForLocs) { + m_coord2dLoc = program->attributeLocation("coord2d"); m_textureTransformLoc = program->uniformLocation("textureTransform"); m_vertexTransformLoc = program->uniformLocation("vertexTransform"); m_dataTextureLoc = program->uniformLocation("dataTexture"); @@ -414,17 +438,28 @@ void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, program->setUniformValueArray(m_lightPosLoc, lightPos, 1, 3); } + if (m_vao) { + m_vao->bind(); + } + f->glEnable(GL_DEPTH_TEST); f->glPolygonOffset(1, 0); f->glEnable(GL_POLYGON_OFFSET_FILL); - int attribute_coord2d = program->attributeLocation("coord2d"); - f->glEnableVertexAttribArray(attribute_coord2d); - m_vertexBuf.bind(); - f->glVertexAttribPointer(attribute_coord2d, 2, GL_FLOAT, GL_FALSE, 0, 0); + m_vertexBuf->bind(); + if (m_vao) + { + program->enableAttributeArray(m_coord2dLoc); + program->setAttributeBuffer(m_coord2dLoc, GL_FLOAT, 0, 2); + } + else + { + f->glEnableVertexAttribArray(m_coord2dLoc); + f->glVertexAttribPointer(m_coord2dLoc, 2, GL_FLOAT, GL_FALSE, 0, 0); + } - m_index1Buf.bind(); + m_index1Buf->bind(); switch (style) { case SpectrumSettings::Points: @@ -447,14 +482,29 @@ void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, { // Draw the outline program->setUniformValue(m_brightnessLoc, 1.5f); - m_index0Buf.bind(); + m_index0Buf->bind(); f->glDrawElements(GL_LINES, m_gridElements * (m_gridElements+1) * 4, GL_UNSIGNED_INT, 0); } - f->glDisableVertexAttribArray(attribute_coord2d); - // Need to do this, otherwise nothing else is drawn... - f->glBindBuffer(GL_ARRAY_BUFFER, 0); - f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + if (m_vao) { + program->disableAttributeArray(m_coord2dLoc); + } else { + f->glDisableVertexAttribArray(m_coord2dLoc); + } + + if (m_vao) + { + m_vao->release(); + m_vertexBuf->release(); + m_index0Buf->release(); + m_index1Buf->release(); + } + else + { + // Need to do this, otherwise nothing else is drawn by other shaders + f->glBindBuffer(GL_ARRAY_BUFFER, 0); + f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); + } // If this is left enabled, channel markers aren't drawn properly f->glDisable(GL_DEPTH_TEST); @@ -464,30 +514,26 @@ void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, void GLShaderSpectrogram::cleanup() { + delete m_programShaded; + m_programShaded = nullptr; + delete m_programSimple; + m_programSimple = nullptr; + m_programForLocs = nullptr; + delete m_texture; + m_texture = nullptr; + delete m_colorMapTexture; + m_colorMapTexture = nullptr; + delete m_vertexBuf; + m_vertexBuf = nullptr; + delete m_index0Buf; + m_index0Buf = nullptr; + delete m_index1Buf; + m_index1Buf = nullptr; + if (!QOpenGLContext::currentContext()) { return; } - if (m_programShaded) - { - delete m_programShaded; - m_programShaded = nullptr; - } - - if (m_programSimple) - { - delete m_programSimple; - m_programSimple = nullptr; - } - - m_programForLocs = nullptr; - - if (m_texture) - { - delete m_texture; - m_texture = nullptr; - } - if (m_textureId) { glDeleteTextures(1, &m_textureId); @@ -499,12 +545,6 @@ void GLShaderSpectrogram::cleanup() glDeleteTextures(1, &m_colorMapTextureId); m_colorMapTextureId = 0; } - - if (m_colorMapTexture) - { - delete m_colorMapTexture; - m_colorMapTexture = nullptr; - } } bool GLShaderSpectrogram::useImmutableStorage() diff --git a/sdrgui/gui/glshaderspectrogram.h b/sdrgui/gui/glshaderspectrogram.h index b33eb963f..5b196b0c6 100644 --- a/sdrgui/gui/glshaderspectrogram.h +++ b/sdrgui/gui/glshaderspectrogram.h @@ -83,6 +83,7 @@ private: unsigned int m_colorMapTextureId; QOpenGLShaderProgram *m_programForLocs; // Which program the locations are for + int m_coord2dLoc; int m_textureTransformLoc; int m_vertexTransformLoc; int m_dataTextureLoc; @@ -100,9 +101,10 @@ private: static const QString m_fragmentShaderSimple2; static const QString m_fragmentShaderSimple; - QOpenGLBuffer m_vertexBuf; - QOpenGLBuffer m_index0Buf; - QOpenGLBuffer m_index1Buf; + QOpenGLVertexArrayObject *m_vao; + QOpenGLBuffer *m_vertexBuf; + QOpenGLBuffer *m_index0Buf; + QOpenGLBuffer *m_index1Buf; float m_translateX; float m_translateY; diff --git a/sdrgui/gui/glshadertextured.cpp b/sdrgui/gui/glshadertextured.cpp index 76168b4e4..e23f94884 100644 --- a/sdrgui/gui/glshadertextured.cpp +++ b/sdrgui/gui/glshadertextured.cpp @@ -28,7 +28,12 @@ GLShaderTextured::GLShaderTextured() : m_program(nullptr), + m_vao(nullptr), + m_verticesBuf(nullptr), + m_textureCoordsBuf(nullptr), m_texture(nullptr), + m_vertexLoc(0), + m_texCoordLoc(0), m_textureId(0), m_matrixLoc(0), m_textureLoc(0), @@ -74,8 +79,23 @@ void GLShaderTextured::initializeGL(int majorVersion, int minorVersion) } m_program->bind(); + m_vertexLoc = m_program->attributeLocation("vertex"); + m_texCoordLoc = m_program->attributeLocation("texCoord"); m_matrixLoc = m_program->uniformLocation("uMatrix"); m_textureLoc = m_program->uniformLocation("uTexture"); + if (m_vao) + { + m_vao = new QOpenGLVertexArrayObject(); + m_vao->create(); + m_vao->bind(); + m_verticesBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + m_verticesBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw); + m_verticesBuf->create(); + m_textureCoordsBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + m_textureCoordsBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw); + m_textureCoordsBuf->create(); + m_vao->release(); + } m_program->release(); } @@ -176,12 +196,39 @@ void GLShaderTextured::draw(unsigned int mode, const QMatrix4x4& transformMatrix m_program->setUniformValue(m_matrixLoc, transformMatrix); m_texture->bind(); m_program->setUniformValue(m_textureLoc, 0); // Use texture unit 0 which magically contains our texture - f->glEnableVertexAttribArray(0); // vertex - f->glVertexAttribPointer(0, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); - f->glEnableVertexAttribArray(1); // texture coordinates - f->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); + if (m_vao) + { + m_vao->bind(); + + m_verticesBuf->bind(); + m_verticesBuf->allocate(vertices, nbVertices * nbComponents * sizeof(GL_FLOAT)); + m_program->enableAttributeArray(m_vertexLoc); + m_program->setAttributeBuffer(m_vertexLoc, GL_FLOAT, 0, nbComponents); + + m_textureCoordsBuf->bind(); + m_textureCoordsBuf->allocate(textureCoords, nbVertices * 2 * sizeof(GL_FLOAT)); + m_program->enableAttributeArray(m_texCoordLoc); + m_program->setAttributeBuffer(m_texCoordLoc, GL_FLOAT, 0, 2); + } + else + { + f->glEnableVertexAttribArray(m_vertexLoc); // vertex + f->glVertexAttribPointer(m_vertexLoc, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); + f->glEnableVertexAttribArray(m_texCoordLoc); // texture coordinates + f->glVertexAttribPointer(m_texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); + } + f->glDrawArrays(mode, 0, nbVertices); - f->glDisableVertexAttribArray(0); + + if (m_vao) + { + m_vao->release(); + } + else + { + f->glDisableVertexAttribArray(m_vertexLoc); + f->glDisableVertexAttribArray(m_texCoordLoc); + } m_program->release(); } @@ -197,33 +244,33 @@ void GLShaderTextured::drawMutable(unsigned int mode, const QMatrix4x4& transfor m_program->setUniformValue(m_matrixLoc, transformMatrix); glBindTexture(GL_TEXTURE_2D, m_textureId); m_program->setUniformValue(m_textureLoc, 0); // Use texture unit 0 which magically contains our texture - glEnableVertexAttribArray(0); // vertex - glVertexAttribPointer(0, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); - glEnableVertexAttribArray(1); // texture coordinates - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); + glEnableVertexAttribArray(m_vertexLoc); // vertex + glVertexAttribPointer(m_vertexLoc, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); + glEnableVertexAttribArray(m_texCoordLoc); // texture coordinates + glVertexAttribPointer(m_texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); glDrawArrays(mode, 0, nbVertices); - glDisableVertexAttribArray(0); + glDisableVertexAttribArray(m_vertexLoc); + glDisableVertexAttribArray(m_texCoordLoc); m_program->release(); } void GLShaderTextured::cleanup() { + delete m_program; + m_program = nullptr; + delete m_vao; + m_vao = nullptr; + delete m_verticesBuf; + m_verticesBuf = nullptr; + delete m_textureCoordsBuf; + m_textureCoordsBuf = nullptr; + delete m_texture; + m_texture = nullptr; + if (!QOpenGLContext::currentContext()) { return; } - if (m_program) - { - delete m_program; - m_program = nullptr; - } - - if (m_texture) - { - delete m_texture; - m_texture = nullptr; - } - if (m_textureId) { glDeleteTextures(1, &m_textureId); diff --git a/sdrgui/gui/glshadertextured.h b/sdrgui/gui/glshadertextured.h index 868a26f1d..a92b0d98e 100644 --- a/sdrgui/gui/glshadertextured.h +++ b/sdrgui/gui/glshadertextured.h @@ -25,6 +25,8 @@ #include #include #include +#include +#include #include "export.h" @@ -54,8 +56,13 @@ private: bool useImmutableStorage(); QOpenGLShaderProgram *m_program; + QOpenGLVertexArrayObject *m_vao; + QOpenGLBuffer *m_verticesBuf; + QOpenGLBuffer *m_textureCoordsBuf; QOpenGLTexture *m_texture; unsigned int m_textureId; + int m_vertexLoc; + int m_texCoordLoc; int m_matrixLoc; int m_textureLoc; bool m_useImmutableStorage; From 0a91c300385b61157f8363b53eee1191908dd75c Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sun, 19 Jun 2022 11:39:13 +0100 Subject: [PATCH 06/12] Create VAOs properly --- sdrgui/gui/glshadersimple.cpp | 7 ++++--- sdrgui/gui/glshadertextured.cpp | 9 +++++---- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/sdrgui/gui/glshadersimple.cpp b/sdrgui/gui/glshadersimple.cpp index ef6b7244a..f52c245da 100644 --- a/sdrgui/gui/glshadersimple.cpp +++ b/sdrgui/gui/glshadersimple.cpp @@ -51,6 +51,10 @@ void GLShaderSimple::initializeGL(int majorVersion, int minorVersion) if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceColored)) { qDebug() << "GLShaderSimple::initializeGL: error in fragment shader: " << m_program->log(); } + + m_vao = new QOpenGLVertexArrayObject(); + m_vao->create(); + m_vao->bind(); } else { @@ -74,9 +78,6 @@ void GLShaderSimple::initializeGL(int majorVersion, int minorVersion) m_colorLoc = m_program->uniformLocation("uColour"); if (m_vao) { - m_vao = new QOpenGLVertexArrayObject(); - m_vao->create(); - m_vao->bind(); m_verticesBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); m_verticesBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw); m_verticesBuf->create(); diff --git a/sdrgui/gui/glshadertextured.cpp b/sdrgui/gui/glshadertextured.cpp index e23f94884..b9e2a4db0 100644 --- a/sdrgui/gui/glshadertextured.cpp +++ b/sdrgui/gui/glshadertextured.cpp @@ -32,9 +32,9 @@ GLShaderTextured::GLShaderTextured() : m_verticesBuf(nullptr), m_textureCoordsBuf(nullptr), m_texture(nullptr), + m_textureId(0), m_vertexLoc(0), m_texCoordLoc(0), - m_textureId(0), m_matrixLoc(0), m_textureLoc(0), m_useImmutableStorage(true) @@ -60,6 +60,10 @@ void GLShaderTextured::initializeGL(int majorVersion, int minorVersion) if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceTextured)) { qDebug() << "GLShaderTextured::initializeGL: error in fragment shader: " << m_program->log(); } + + m_vao = new QOpenGLVertexArrayObject(); + m_vao->create(); + m_vao->bind(); } else { @@ -85,9 +89,6 @@ void GLShaderTextured::initializeGL(int majorVersion, int minorVersion) m_textureLoc = m_program->uniformLocation("uTexture"); if (m_vao) { - m_vao = new QOpenGLVertexArrayObject(); - m_vao->create(); - m_vao->bind(); m_verticesBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); m_verticesBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw); m_verticesBuf->create(); From 37622db67863c4050641b65adb7ac43db339cf55 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sun, 19 Jun 2022 14:16:45 +0100 Subject: [PATCH 07/12] Optimise VAO usage --- sdrgui/gui/glshadercolors.cpp | 70 +++++++++++++++++++++++------- sdrgui/gui/glshadercolors.h | 5 +++ sdrgui/gui/glshaderspectrogram.cpp | 43 ++++++++---------- 3 files changed, 79 insertions(+), 39 deletions(-) diff --git a/sdrgui/gui/glshadercolors.cpp b/sdrgui/gui/glshadercolors.cpp index d005ad94c..65bdbceb2 100644 --- a/sdrgui/gui/glshadercolors.cpp +++ b/sdrgui/gui/glshadercolors.cpp @@ -27,6 +27,9 @@ GLShaderColors::GLShaderColors() : m_program(nullptr), + m_vao(nullptr), + m_verticesBuf(nullptr), + m_colorBuf(nullptr), m_matrixLoc(0), m_alphaLoc(0) { } @@ -48,6 +51,10 @@ void GLShaderColors::initializeGL(int majorVersion, int minorVersion) if (!m_program->addShaderFromSourceCode(QOpenGLShader::Fragment, m_fragmentShaderSourceColored)) { qDebug() << "GLShaderColors::initializeGL: error in fragment shader: " << m_program->log(); } + + m_vao = new QOpenGLVertexArrayObject(); + m_vao->create(); + m_vao->bind(); } else { @@ -69,6 +76,16 @@ void GLShaderColors::initializeGL(int majorVersion, int minorVersion) m_program->bind(); m_matrixLoc = m_program->uniformLocation("uMatrix"); m_alphaLoc = m_program->uniformLocation("uAlpha"); + if (m_vao) + { + m_verticesBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + m_verticesBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw); + m_verticesBuf->create(); + m_colorBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + m_colorBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw); + m_colorBuf->create(); + m_vao->release(); + } m_program->release(); } @@ -106,27 +123,50 @@ void GLShaderColors::draw(unsigned int mode, const QMatrix4x4& transformMatrix, f->glEnable(GL_BLEND); f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); f->glLineWidth(1.0f); - f->glEnableVertexAttribArray(0); // vertex - f->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices); - f->glEnableVertexAttribArray(1); // colors - f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, colors); + if (m_vao) + { + m_vao->bind(); + + m_verticesBuf->bind(); + m_verticesBuf->allocate(vertices, nbVertices * 2 * sizeof(GL_FLOAT)); + m_program->enableAttributeArray(0); + m_program->setAttributeBuffer(0, GL_FLOAT, 0, 2); + + m_colorBuf->bind(); + m_colorBuf->allocate(colors, nbVertices * 3 * sizeof(GL_FLOAT)); + m_program->enableAttributeArray(1); + m_program->setAttributeBuffer(1, GL_FLOAT, 0, 3); + } + else + { + f->glEnableVertexAttribArray(0); // vertex + f->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertices); + f->glEnableVertexAttribArray(1); // colors + f->glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 0, colors); + } f->glDrawArrays(mode, 0, nbVertices); - f->glDisableVertexAttribArray(0); - f->glDisableVertexAttribArray(1); + if (m_vao) + { + m_vao->release(); + } + else + { + f->glDisableVertexAttribArray(0); + f->glDisableVertexAttribArray(1); + } m_program->release(); } void GLShaderColors::cleanup() { - if (!QOpenGLContext::currentContext()) { - return; - } - - if (m_program) - { - delete m_program; - m_program = nullptr; - } + delete m_program; + m_program = nullptr; + delete m_vao; + m_vao = nullptr; + delete m_verticesBuf; + m_verticesBuf = nullptr; + delete m_colorBuf; + m_colorBuf = nullptr; } const QString GLShaderColors::m_vertexShaderSourceSimple2 = QString( diff --git a/sdrgui/gui/glshadercolors.h b/sdrgui/gui/glshadercolors.h index cf5f9ca38..614d96a1a 100644 --- a/sdrgui/gui/glshadercolors.h +++ b/sdrgui/gui/glshadercolors.h @@ -24,6 +24,8 @@ #include #include +#include +#include #include "export.h" @@ -49,6 +51,9 @@ private: void draw(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *vertices, GLfloat *colors, GLfloat alpha, int nbVertices); QOpenGLShaderProgram *m_program; + QOpenGLVertexArrayObject *m_vao; + QOpenGLBuffer *m_verticesBuf; + QOpenGLBuffer *m_colorBuf; int m_matrixLoc; int m_alphaLoc; static const QString m_vertexShaderSourceSimple2; diff --git a/sdrgui/gui/glshaderspectrogram.cpp b/sdrgui/gui/glshaderspectrogram.cpp index 2b3a702f3..db09e1081 100644 --- a/sdrgui/gui/glshaderspectrogram.cpp +++ b/sdrgui/gui/glshaderspectrogram.cpp @@ -169,9 +169,20 @@ void GLShaderSpectrogram::initGrid(int elements) m_vertexBuf->bind(); m_vertexBuf->allocate(&vertices[0], vertices.size() * sizeof(QVector2D)); - // Create an array of indices into the vertex array that traces both horizontal and vertical lines + if (m_vao) + { + m_programShaded->enableAttributeArray(m_coord2dLoc); + m_programShaded->setAttributeBuffer(m_coord2dLoc, GL_FLOAT, 0, 2); + m_programSimple->enableAttributeArray(m_coord2dLoc); + m_programSimple->setAttributeBuffer(m_coord2dLoc, GL_FLOAT, 0, 2); + m_vao->release(); + } + std::vector indices(m_gridElements * m_gridElements * 6); - int i = 0; + int i; + + // Create an array of indices into the vertex array that traces both horizontal and vertical lines + i = 0; for (int y = 0; y < e1; y++) { for (int x = 0; x < m_gridElements; x++) { @@ -190,7 +201,7 @@ void GLShaderSpectrogram::initGrid(int elements) m_index0Buf->bind(); m_index0Buf->allocate(&indices[0], m_gridElements * (e1) * 4 * sizeof(GLuint)); - // Create another array of indices that describes all the triangles needed to create a completely filled surface + // Create an array of indices that describes all the triangles needed to create a completely filled surface i = 0; for (int y = 0; y < m_gridElements; y++) { @@ -208,11 +219,7 @@ void GLShaderSpectrogram::initGrid(int elements) m_index1Buf->bind(); m_index1Buf->allocate(&indices[0], indices.size() * sizeof(GLuint)); - if (m_vao) - { - m_vao->release(); - } - else + if (!m_vao) { QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); f->glBindBuffer(GL_ARRAY_BUFFER, 0); @@ -438,28 +445,23 @@ void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, program->setUniformValueArray(m_lightPosLoc, lightPos, 1, 3); } - if (m_vao) { - m_vao->bind(); - } - f->glEnable(GL_DEPTH_TEST); f->glPolygonOffset(1, 0); f->glEnable(GL_POLYGON_OFFSET_FILL); - m_vertexBuf->bind(); if (m_vao) { - program->enableAttributeArray(m_coord2dLoc); - program->setAttributeBuffer(m_coord2dLoc, GL_FLOAT, 0, 2); + m_vao->bind(); } else { + m_vertexBuf->bind(); f->glEnableVertexAttribArray(m_coord2dLoc); f->glVertexAttribPointer(m_coord2dLoc, 2, GL_FLOAT, GL_FALSE, 0, 0); } - m_index1Buf->bind(); + switch (style) { case SpectrumSettings::Points: @@ -486,21 +488,14 @@ void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, f->glDrawElements(GL_LINES, m_gridElements * (m_gridElements+1) * 4, GL_UNSIGNED_INT, 0); } - if (m_vao) { - program->disableAttributeArray(m_coord2dLoc); - } else { - f->glDisableVertexAttribArray(m_coord2dLoc); - } - if (m_vao) { m_vao->release(); - m_vertexBuf->release(); m_index0Buf->release(); - m_index1Buf->release(); } else { + f->glDisableVertexAttribArray(m_coord2dLoc); // Need to do this, otherwise nothing else is drawn by other shaders f->glBindBuffer(GL_ARRAY_BUFFER, 0); f->glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); From 72dfe95a5bca69edb51b23325a8159677163a5ca Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sun, 19 Jun 2022 21:37:24 +0100 Subject: [PATCH 08/12] GL_LUMINANCE is deprecate so doesn't work on Mac. Use GL_RED instead. --- sdrgui/gui/glshaderspectrogram.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/sdrgui/gui/glshaderspectrogram.cpp b/sdrgui/gui/glshaderspectrogram.cpp index db09e1081..57775a919 100644 --- a/sdrgui/gui/glshaderspectrogram.cpp +++ b/sdrgui/gui/glshaderspectrogram.cpp @@ -313,8 +313,8 @@ void GLShaderSpectrogram::initTextureMutable(const QImage& image) glGenTextures(1, &m_textureId); glBindTexture(GL_TEXTURE_2D, m_textureId); - glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, - image.width(), image.height(), 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, image.constScanLine(0)); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RED, + image.width(), image.height(), 0, GL_RED, GL_UNSIGNED_BYTE, image.constScanLine(0)); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -341,7 +341,7 @@ void GLShaderSpectrogram::subTextureImmutable(int xOffset, int yOffset, int widt QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); m_texture->bind(); - f->glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels); + f->glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height, GL_RED, GL_UNSIGNED_BYTE, pixels); } void GLShaderSpectrogram::subTextureMutable(int xOffset, int yOffset, int width, int height, const void *pixels) @@ -353,7 +353,7 @@ void GLShaderSpectrogram::subTextureMutable(int xOffset, int yOffset, int width, } glBindTexture(GL_TEXTURE_2D, m_textureId); - glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height, GL_LUMINANCE, GL_UNSIGNED_BYTE, pixels); + glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height, GL_RED, GL_UNSIGNED_BYTE, pixels); } void GLShaderSpectrogram::drawSurface(SpectrumSettings::SpectrogramStyle style, const QMatrix4x4& vertexTransform, float textureOffset, bool invert) From 3335dd7cc09f4886a9dec1cf25dc5b0249902358 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sun, 19 Jun 2022 22:09:37 +0100 Subject: [PATCH 09/12] Default to OpenGL 3.3 context on Mac, as we otherwise get 2.1 --- app/main.cpp | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/app/main.cpp b/app/main.cpp index ae0a7b40d..8210277a8 100644 --- a/app/main.cpp +++ b/app/main.cpp @@ -22,6 +22,8 @@ #include #include #include +#include +#include #include "loggerwithfile.h" #include "mainwindow.h" @@ -134,10 +136,19 @@ static int runQtApplication(int argc, char* argv[], qtwebapp::LoggerWithFile *lo int main(int argc, char* argv[]) { #ifdef __APPLE__ - // Enable WebGL in QtWebEngine when OpenGL is only version 2.1 (Needed for 3D Map) - // This can be removed when we eventually request a 4.1 OpenGL context - // This needs to be executed before any other Qt code - qputenv("QTWEBENGINE_CHROMIUM_FLAGS", "--ignore-gpu-blacklist"); + // Request OpenGL 3.3 context, needed for glspectrum and 3D Map feature + // Note that Mac only supports CoreProfile, so any deprecated OpenGL 2 features + // will not work. Because of this, we have two versions of the shaders: + // OpenGL 2 versions for compatiblity with older drivers and OpenGL 3.3 + // versions for newer drivers + QGLFormat fmt; + fmt.setVersion(3, 3); + fmt.setProfile(QGLFormat::CoreProfile); + QGLFormat::setDefaultFormat(fmt); + QSurfaceFormat sfc; + sfc.setVersion(3, 3); + sfc.setProfile(QSurfaceFormat::CoreProfile); + QSurfaceFormat::setDefaultFormat(sfc); #endif qtwebapp::LoggerWithFile *logger = new qtwebapp::LoggerWithFile(qApp); From 34ce5ae3989a31dcb57a9505b0d3b40c36838b3a Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sun, 19 Jun 2022 22:14:26 +0100 Subject: [PATCH 10/12] Support high DPI devices --- sdrgui/gui/glspectrum.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/sdrgui/gui/glspectrum.cpp b/sdrgui/gui/glspectrum.cpp index f7d7fafe9..87c0d0d50 100644 --- a/sdrgui/gui/glspectrum.cpp +++ b/sdrgui/gui/glspectrum.cpp @@ -23,6 +23,7 @@ #include #include #include +#include #include "maincore.h" #include "dsp/spectrumvis.h" #include "gui/glspectrum.h" @@ -784,10 +785,11 @@ void GLSpectrum::initializeGL() qDebug() << "GLSpectrum::initializeGL: current context is invalid"; } - if ( (MainCore::instance()->getSettings().getConsoleMinLogLevel() <= QtDebugMsg) - || (MainCore::instance()->getSettings().getFileMinLogLevel() <= QtDebugMsg)) + // Enable OpenGL debugging + // Disable for release, as some OpenGL drivers are quite verbose and output + // info on every frame + if (false) { - // Enable OpenGL debugging QSurfaceFormat format = glCurrentContext->format(); format.setOption(QSurfaceFormat::DebugContext); glCurrentContext->setFormat(format); @@ -877,6 +879,7 @@ void GLSpectrum::paintGL() glFunctions->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); QMatrix4x4 spectrogramGridMatrix; + int devicePixelRatio; if (m_display3DSpectrogram) { @@ -901,9 +904,14 @@ void GLSpectrum::paintGL() float prop_y = m_3DSpectrogramTexturePos / (m_3DSpectrogramTextureHeight - 1.0); // Temporarily reduce viewport to waterfall area so anything outside is clipped - glFunctions->glViewport(0, m_3DSpectrogramBottom, width(), m_waterfallHeight); + if (window()->windowHandle()) { + devicePixelRatio = window()->windowHandle()->devicePixelRatio(); + } else { + devicePixelRatio = 1; + } + glFunctions->glViewport(0, m_3DSpectrogramBottom*devicePixelRatio, width()*devicePixelRatio, m_waterfallHeight*devicePixelRatio); m_glShaderSpectrogram.drawSurface(m_3DSpectrogramStyle, spectrogramGridMatrix, prop_y, m_invertedWaterfall); - glFunctions->glViewport(0, 0, width(), height()); + glFunctions->glViewport(0, 0, width()*devicePixelRatio, height()*devicePixelRatio); } else if (m_displayWaterfall) { @@ -1168,7 +1176,7 @@ void GLSpectrum::paintGL() // paint 3D spectrogram scales if (m_display3DSpectrogram && m_displayGrid) { - glFunctions->glViewport(0, m_3DSpectrogramBottom, width(), m_waterfallHeight); + glFunctions->glViewport(0, m_3DSpectrogramBottom*devicePixelRatio, width()*devicePixelRatio, m_waterfallHeight*devicePixelRatio); { GLfloat l = m_spectrogramTimePixmap.width() / (GLfloat) width(); GLfloat r = m_rightMargin / (GLfloat) width(); @@ -1230,7 +1238,7 @@ void GLSpectrum::paintGL() m_glShaderSpectrogramPowerScale.drawSurface(spectrogramGridMatrix, tex1, vtx1, 4, 3); } - glFunctions->glViewport(0, 0, width(), height()); + glFunctions->glViewport(0, 0, width()*devicePixelRatio, height()*devicePixelRatio); } // paint max hold lines on top of histogram @@ -1379,7 +1387,7 @@ void GLSpectrum::paintGL() const ScaleEngine::TickList* tickList; const ScaleEngine::Tick* tick; - glFunctions->glViewport(0, m_3DSpectrogramBottom, width(), m_waterfallHeight); + glFunctions->glViewport(0, m_3DSpectrogramBottom*devicePixelRatio, width()*devicePixelRatio, m_waterfallHeight*devicePixelRatio); tickList = &m_powerScale.getTickList(); { @@ -1491,7 +1499,7 @@ void GLSpectrum::paintGL() m_glShaderSimple.drawSegments(spectrogramGridMatrix, color, q3, 2*effectiveTicks, 3); } - glFunctions->glViewport(0, 0, width(), height()); + glFunctions->glViewport(0, 0, width()*devicePixelRatio, height()*devicePixelRatio); } // paint histogram grid From 94f93ee9addb55fd20ae19f95572eaf0d93bae80 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Sun, 19 Jun 2022 23:22:43 +0100 Subject: [PATCH 11/12] Update TVScreen to OpenGL 3.3 --- sdrgui/gui/glshadertvarray.cpp | 147 ++++++++++++++++---- sdrgui/gui/glshadertvarray.h | 9 +- sdrgui/gui/tvscreen.cpp | 8 +- sdrgui/gui/tvscreenanalog.cpp | 244 +++++++++++++++++++++++++-------- sdrgui/gui/tvscreenanalog.h | 5 + 5 files changed, 321 insertions(+), 92 deletions(-) diff --git a/sdrgui/gui/glshadertvarray.cpp b/sdrgui/gui/glshadertvarray.cpp index 0ed685258..a01f05221 100644 --- a/sdrgui/gui/glshadertvarray.cpp +++ b/sdrgui/gui/glshadertvarray.cpp @@ -20,25 +20,48 @@ #include "gui/glshadertvarray.h" -const QString GLShaderTVArray::m_strVertexShaderSourceArray = QString( +const QString GLShaderTVArray::m_strVertexShaderSourceArray2 = QString( "uniform highp mat4 uMatrix;\n" - "attribute highp vec4 vertex;\n" - "attribute highp vec2 texCoord;\n" - "varying mediump vec2 texCoordVar;\n" - "void main() {\n" - " gl_Position = uMatrix * vertex;\n" - " texCoordVar = texCoord;\n" - "}\n"); + "attribute highp vec4 vertex;\n" + "attribute highp vec2 texCoord;\n" + "varying mediump vec2 texCoordVar;\n" + "void main() {\n" + " gl_Position = uMatrix * vertex;\n" + " texCoordVar = texCoord;\n" + "}\n"); + +const QString GLShaderTVArray::m_strVertexShaderSourceArray = QString( + "#version 330\n" + "uniform highp mat4 uMatrix;\n" + "in highp vec4 vertex;\n" + "in highp vec2 texCoord;\n" + "out mediump vec2 texCoordVar;\n" + "void main() {\n" + " gl_Position = uMatrix * vertex;\n" + " texCoordVar = texCoord;\n" + "}\n"); + +const QString GLShaderTVArray::m_strFragmentShaderSourceColored2 = QString( + "uniform lowp sampler2D uTexture;\n" + "varying mediump vec2 texCoordVar;\n" + "void main() {\n" + " gl_FragColor = texture2D(uTexture, texCoordVar);\n" + "}\n"); const QString GLShaderTVArray::m_strFragmentShaderSourceColored = QString( + "#version 330\n" "uniform lowp sampler2D uTexture;\n" - "varying mediump vec2 texCoordVar;\n" - "void main() {\n" - " gl_FragColor = texture2D(uTexture, texCoordVar);\n" - "}\n"); + "in mediump vec2 texCoordVar;\n" + "out vec4 fragColor;\n" + "void main() {\n" + " fragColor = texture(uTexture, texCoordVar);\n" + "}\n"); GLShaderTVArray::GLShaderTVArray(bool blnColor) : m_objProgram(nullptr), + m_vao(nullptr), + m_verticesBuf(nullptr), + m_textureCoordsBuf(nullptr), m_matrixLoc(0), m_textureLoc(0), m_objImage(nullptr), @@ -59,7 +82,7 @@ GLShaderTVArray::~GLShaderTVArray() cleanup(); } -void GLShaderTVArray::initializeGL(int intCols, int intRows) +void GLShaderTVArray::initializeGL(int majorVersion, int minorVersion, int intCols, int intRows) { QMatrix4x4 objQMatrix; @@ -73,20 +96,43 @@ void GLShaderTVArray::initializeGL(int intCols, int intRows) if (!m_objProgram) { m_objProgram = new QOpenGLShaderProgram(); - - if (!m_objProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, - m_strVertexShaderSourceArray)) + if ((majorVersion > 3) || ((majorVersion == 3) && (minorVersion >= 3))) { - qDebug() << "GLShaderArray::initializeGL: error in vertex shader: " - << m_objProgram->log(); + if (!m_objProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, + m_strVertexShaderSourceArray)) + { + qDebug() << "GLShaderArray::initializeGL: error in vertex shader: " + << m_objProgram->log(); + } + + if (!m_objProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, + m_strFragmentShaderSourceColored)) + { + qDebug() + << "GLShaderArray::initializeGL: error in fragment shader: " + << m_objProgram->log(); + } + + m_vao = new QOpenGLVertexArrayObject(); + m_vao->create(); + m_vao->bind(); } - - if (!m_objProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, - m_strFragmentShaderSourceColored)) + else { - qDebug() - << "GLShaderArray::initializeGL: error in fragment shader: " - << m_objProgram->log(); + if (!m_objProgram->addShaderFromSourceCode(QOpenGLShader::Vertex, + m_strVertexShaderSourceArray2)) + { + qDebug() << "GLShaderArray::initializeGL: error in vertex shader: " + << m_objProgram->log(); + } + + if (!m_objProgram->addShaderFromSourceCode(QOpenGLShader::Fragment, + m_strFragmentShaderSourceColored2)) + { + qDebug() + << "GLShaderArray::initializeGL: error in fragment shader: " + << m_objProgram->log(); + } } m_objProgram->bindAttributeLocation("vertex", 0); @@ -100,6 +146,16 @@ void GLShaderTVArray::initializeGL(int intCols, int intRows) m_objProgram->bind(); m_objProgram->setUniformValue(m_matrixLoc, objQMatrix); m_objProgram->setUniformValue(m_textureLoc, 0); + if (m_vao) + { + m_verticesBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + m_verticesBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw); + m_verticesBuf->create(); + m_textureCoordsBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + m_textureCoordsBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw); + m_textureCoordsBuf->create(); + m_vao->release(); + } m_objProgram->release(); } @@ -232,17 +288,41 @@ void GLShaderTVArray::RenderPixels(unsigned char *chrData) ptrF->glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, m_intCols, m_intRows, GL_RGBA, GL_UNSIGNED_BYTE, m_objImage->bits()); - ptrF->glEnableVertexAttribArray(0); // vertex - ptrF->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, arrVertices); + if (m_vao) + { + m_vao->bind(); - ptrF->glEnableVertexAttribArray(1); // texture coordinates - ptrF->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, arrTextureCoords); + m_verticesBuf->bind(); + m_verticesBuf->allocate(arrVertices, intNbVertices * 2 * sizeof(GL_FLOAT)); + m_objProgram->enableAttributeArray(0); + m_objProgram->setAttributeBuffer(0, GL_FLOAT, 0, 2); + + m_textureCoordsBuf->bind(); + m_textureCoordsBuf->allocate(arrTextureCoords, intNbVertices * 2 * sizeof(GL_FLOAT)); + m_objProgram->enableAttributeArray(1); + m_objProgram->setAttributeBuffer(1, GL_FLOAT, 0, 2); + } + else + { + ptrF->glEnableVertexAttribArray(0); // vertex + ptrF->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, arrVertices); + + ptrF->glEnableVertexAttribArray(1); // texture coordinates + ptrF->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, arrTextureCoords); + } ptrF->glDrawArrays(GL_TRIANGLES, 0, intNbVertices); //cleanup - ptrF->glDisableVertexAttribArray(0); - ptrF->glDisableVertexAttribArray(1); + if (m_vao) + { + m_vao->release(); + } + else + { + ptrF->glDisableVertexAttribArray(0); + ptrF->glDisableVertexAttribArray(1); + } //*********************// @@ -294,6 +374,13 @@ void GLShaderTVArray::cleanup() delete m_objImage; m_objImage = nullptr; } + + delete m_verticesBuf; + m_verticesBuf = nullptr; + delete m_textureCoordsBuf; + m_textureCoordsBuf = nullptr; + delete m_vao; + m_vao = nullptr; } bool GLShaderTVArray::SelectRow(int intLine) diff --git a/sdrgui/gui/glshadertvarray.h b/sdrgui/gui/glshadertvarray.h index 4a2ce35f5..200105ad8 100644 --- a/sdrgui/gui/glshadertvarray.h +++ b/sdrgui/gui/glshadertvarray.h @@ -26,6 +26,8 @@ #include #include #include +#include +#include #include #include #include @@ -45,7 +47,7 @@ public: void setColor(bool blnColor) { m_blnColor = blnColor; } void setAlphaBlend(bool blnAlphaBlend) { m_blnAlphaBlend = blnAlphaBlend; } void setAlphaReset() { m_blnAlphaReset = true; } - void initializeGL(int intCols, int intRows); + void initializeGL(int majorVersion, int minorVersion, int intCols, int intRows); void cleanup(); QRgb *GetRowBuffer(int intRow); void RenderPixels(unsigned char *chrData); @@ -57,10 +59,15 @@ public: protected: QOpenGLShaderProgram *m_objProgram; + QOpenGLVertexArrayObject *m_vao; + QOpenGLBuffer *m_verticesBuf; + QOpenGLBuffer *m_textureCoordsBuf; int m_matrixLoc; int m_textureLoc; //int m_objColorLoc; + static const QString m_strVertexShaderSourceArray2; static const QString m_strVertexShaderSourceArray; + static const QString m_strFragmentShaderSourceColored2; static const QString m_strFragmentShaderSourceColored; QImage *m_objImage; diff --git a/sdrgui/gui/tvscreen.cpp b/sdrgui/gui/tvscreen.cpp index ad49c773d..5227478e9 100644 --- a/sdrgui/gui/tvscreen.cpp +++ b/sdrgui/gui/tvscreen.cpp @@ -178,7 +178,13 @@ void TVScreen::paintGL() if ((m_askedCols != 0) && (m_askedRows != 0)) { - m_glShaderArray.initializeGL(m_askedCols, m_askedRows); + int major = 0, minor = 0; + if (QOpenGLContext::currentContext()) + { + major = QOpenGLContext::currentContext()->format().majorVersion(); + minor = QOpenGLContext::currentContext()->format().minorVersion(); + } + m_glShaderArray.initializeGL(major, minor, m_askedCols, m_askedRows); m_askedCols = 0; m_askedRows = 0; } diff --git a/sdrgui/gui/tvscreenanalog.cpp b/sdrgui/gui/tvscreenanalog.cpp index 28c2d9506..130fe9c1c 100644 --- a/sdrgui/gui/tvscreenanalog.cpp +++ b/sdrgui/gui/tvscreenanalog.cpp @@ -21,52 +21,101 @@ #include "tvscreenanalog.h" +static const char* vertexShaderSource2 = + "attribute highp vec4 vertex;\n" + "attribute highp vec2 texCoord;\n" + "varying highp vec2 texCoordVar;\n" + "void main() {\n" + " gl_Position = vertex;\n" + " texCoordVar = texCoord;\n" + "}\n"; + static const char* vertexShaderSource = -"attribute highp vec4 vertex;\n" -"attribute highp vec2 texCoord;\n" -"varying highp vec2 texCoordVar;\n" -"void main() {\n" -" gl_Position = vertex;\n" -" texCoordVar = texCoord;\n" -"}\n"; + "#version 330\n" + "in highp vec4 vertex;\n" + "in highp vec2 texCoord;\n" + "out highp vec2 texCoordVar;\n" + "void main() {\n" + " gl_Position = vertex;\n" + " texCoordVar = texCoord;\n" + "}\n"; + +static const char* fragmentShaderSource2 = + "uniform highp sampler2D tex1;\n" + "uniform highp sampler2D tex2;\n" + "uniform highp float imw;\n" + "uniform highp float imh;\n" + "uniform highp float tlw;\n" + "uniform highp float tlh;\n" + "varying highp vec2 texCoordVar;\n" + "void main() {\n" + " float tlhw = 0.5 * tlw;" + " float tlhh = 0.5 * tlh;" + " float tys = (texCoordVar.y + tlhh) * imh;\n" + " float p1y = floor(tys) * tlh - tlhh;\n" + " float p3y = p1y + tlh;\n" + " float tshift1 = texture2D(tex2, vec2(0.0, p1y)).r;\n" + " float tshift3 = texture2D(tex2, vec2(0.0, p3y)).r;\n" + " float shift1 = (1.0 - tshift1 * 2.0) * tlw;\n" + " float shift3 = (1.0 - tshift3 * 2.0) * tlw;\n" + " float txs1 = (texCoordVar.x + shift1 + tlhw) * imw;\n" + " float txs3 = (texCoordVar.x + shift3 + tlhw) * imw;\n" + " float p1x = floor(txs1) * tlw - tlhw;\n" + " float p3x = floor(txs3) * tlw - tlhw;\n" + " float p2x = p1x + tlw;\n" + " float p4x = p3x + tlw;\n" + " float p1 = texture2D(tex1, vec2(p1x, p1y)).r;\n" + " float p2 = texture2D(tex1, vec2(p2x, p1y)).r;\n" + " float p3 = texture2D(tex1, vec2(p3x, p3y)).r;\n" + " float p4 = texture2D(tex1, vec2(p4x, p3y)).r;\n" + " float p12 = mix(p1, p2, fract(txs1));\n" + " float p34 = mix(p3, p4, fract(txs3));\n" + " float p = mix(p12, p34, fract(tys));\n" + " gl_FragColor = vec4(p);\n" + "}\n"; static const char* fragmentShaderSource = -"uniform highp sampler2D tex1;\n" -"uniform highp sampler2D tex2;\n" -"uniform highp float imw;\n" -"uniform highp float imh;\n" -"uniform highp float tlw;\n" -"uniform highp float tlh;\n" -"varying highp vec2 texCoordVar;\n" -"void main() {\n" -" float tlhw = 0.5 * tlw;" -" float tlhh = 0.5 * tlh;" -" float tys = (texCoordVar.y + tlhh) * imh;\n" -" float p1y = floor(tys) * tlh - tlhh;\n" -" float p3y = p1y + tlh;\n" -" float tshift1 = texture2D(tex2, vec2(0.0, p1y)).r;\n" -" float tshift3 = texture2D(tex2, vec2(0.0, p3y)).r;\n" -" float shift1 = (1.0 - tshift1 * 2.0) * tlw;\n" -" float shift3 = (1.0 - tshift3 * 2.0) * tlw;\n" -" float txs1 = (texCoordVar.x + shift1 + tlhw) * imw;\n" -" float txs3 = (texCoordVar.x + shift3 + tlhw) * imw;\n" -" float p1x = floor(txs1) * tlw - tlhw;\n" -" float p3x = floor(txs3) * tlw - tlhw;\n" -" float p2x = p1x + tlw;\n" -" float p4x = p3x + tlw;\n" -" float p1 = texture2D(tex1, vec2(p1x, p1y)).r;\n" -" float p2 = texture2D(tex1, vec2(p2x, p1y)).r;\n" -" float p3 = texture2D(tex1, vec2(p3x, p3y)).r;\n" -" float p4 = texture2D(tex1, vec2(p4x, p3y)).r;\n" -" float p12 = mix(p1, p2, fract(txs1));\n" -" float p34 = mix(p3, p4, fract(txs3));\n" -" float p = mix(p12, p34, fract(tys));\n" -" gl_FragColor = vec4(p);\n" -"}\n"; + "#version 330\n" + "uniform highp sampler2D tex1;\n" + "uniform highp sampler2D tex2;\n" + "uniform highp float imw;\n" + "uniform highp float imh;\n" + "uniform highp float tlw;\n" + "uniform highp float tlh;\n" + "in highp vec2 texCoordVar;\n" + "out vec4 fragColor;\n" + "void main() {\n" + " float tlhw = 0.5 * tlw;" + " float tlhh = 0.5 * tlh;" + " float tys = (texCoordVar.y + tlhh) * imh;\n" + " float p1y = floor(tys) * tlh - tlhh;\n" + " float p3y = p1y + tlh;\n" + " float tshift1 = texture2D(tex2, vec2(0.0, p1y)).r;\n" + " float tshift3 = texture2D(tex2, vec2(0.0, p3y)).r;\n" + " float shift1 = (1.0 - tshift1 * 2.0) * tlw;\n" + " float shift3 = (1.0 - tshift3 * 2.0) * tlw;\n" + " float txs1 = (texCoordVar.x + shift1 + tlhw) * imw;\n" + " float txs3 = (texCoordVar.x + shift3 + tlhw) * imw;\n" + " float p1x = floor(txs1) * tlw - tlhw;\n" + " float p3x = floor(txs3) * tlw - tlhw;\n" + " float p2x = p1x + tlw;\n" + " float p4x = p3x + tlw;\n" + " float p1 = texture(tex1, vec2(p1x, p1y)).r;\n" + " float p2 = texture(tex1, vec2(p2x, p1y)).r;\n" + " float p3 = texture(tex1, vec2(p3x, p3y)).r;\n" + " float p4 = texture(tex1, vec2(p4x, p3y)).r;\n" + " float p12 = mix(p1, p2, fract(txs1));\n" + " float p34 = mix(p3, p4, fract(txs3));\n" + " float p = mix(p12, p34, fract(tys));\n" + " fragColor = vec4(p);\n" + "}\n"; TVScreenAnalog::TVScreenAnalog(QWidget *parent) : QOpenGLWidget(parent), m_shader(nullptr), + m_vao(nullptr), + m_verticesBuf(nullptr), + m_textureCoordsBuf(nullptr), m_imageTexture(nullptr), m_lineShiftsTexture(nullptr) { @@ -107,7 +156,14 @@ void TVScreenAnalog::cleanup() delete m_lineShiftsTexture; m_lineShiftsTexture = nullptr; } -} + + delete m_verticesBuf; + m_verticesBuf = nullptr; + delete m_textureCoordsBuf; + m_textureCoordsBuf = nullptr; + delete m_vao; + m_vao = nullptr; + } TVScreenAnalogBuffer *TVScreenAnalog::getBackBuffer() { @@ -147,21 +203,52 @@ void TVScreenAnalog::initializeGL() m_shader = new QOpenGLShaderProgram(this); - if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource)) - { - qWarning() - << "TVScreenAnalog::initializeGL: error in vertex shader:" - << m_shader->log(); - return; - } + int majorVersion = 0, minorVersion = 0; + if (QOpenGLContext::currentContext()) + { + majorVersion = QOpenGLContext::currentContext()->format().majorVersion(); + minorVersion = QOpenGLContext::currentContext()->format().minorVersion(); + } + if ((majorVersion > 3) || ((majorVersion == 3) && (minorVersion >= 3))) + { + if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource)) + { + qWarning() + << "TVScreenAnalog::initializeGL: error in vertex shader:" + << m_shader->log(); + return; + } - if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource)) - { - qWarning() - << "TVScreenAnalog::initializeGL: error in fragment shader:" - << m_shader->log(); - return; - } + if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource)) + { + qWarning() + << "TVScreenAnalog::initializeGL: error in fragment shader:" + << m_shader->log(); + return; + } + + m_vao = new QOpenGLVertexArrayObject(); + m_vao->create(); + m_vao->bind(); + } + else + { + if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Vertex, vertexShaderSource2)) + { + qWarning() + << "TVScreenAnalog::initializeGL: error in vertex shader:" + << m_shader->log(); + return; + } + + if (!m_shader->addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShaderSource2)) + { + qWarning() + << "TVScreenAnalog::initializeGL: error in fragment shader:" + << m_shader->log(); + return; + } + } if (!m_shader->link()) { @@ -179,6 +266,16 @@ void TVScreenAnalog::initializeGL() m_imageHeightLoc = m_shader->uniformLocation("imh"); m_texelWidthLoc = m_shader->uniformLocation("tlw"); m_texelHeightLoc = m_shader->uniformLocation("tlh"); + if (m_vao) + { + m_verticesBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + m_verticesBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw); + m_verticesBuf->create(); + m_textureCoordsBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); + m_textureCoordsBuf->setUsagePattern(QOpenGLBuffer::DynamicDraw); + m_textureCoordsBuf->create(); + m_vao->release(); + } } void TVScreenAnalog::initializeTextures(TVScreenAnalogBuffer *buffer) @@ -280,13 +377,40 @@ void TVScreenAnalog::paintGL() 1.0f, 1.0f }; - glVertexAttribPointer(m_vertexAttribIndex, 2, GL_FLOAT, GL_FALSE, 0, vertices); - glEnableVertexAttribArray(m_vertexAttribIndex); - glVertexAttribPointer(m_texCoordAttribIndex, 2, GL_FLOAT, GL_FALSE, 0, arrTextureCoords); - glEnableVertexAttribArray(m_texCoordAttribIndex); + if (m_vao) + { + m_vao->bind(); + + m_verticesBuf->bind(); + m_verticesBuf->allocate(vertices, 4 * 2 * sizeof(GL_FLOAT)); + m_shader->enableAttributeArray(m_vertexAttribIndex); + m_shader->setAttributeBuffer(m_vertexAttribIndex, GL_FLOAT, 0, 2); + + // As these coords are constant, this could be moved into the init method + m_textureCoordsBuf->bind(); + m_textureCoordsBuf->allocate(arrTextureCoords, 4 * 2 * sizeof(GL_FLOAT)); + m_shader->enableAttributeArray(m_texCoordAttribIndex); + m_shader->setAttributeBuffer(m_texCoordAttribIndex, GL_FLOAT, 0, 2); + } + else + { + glVertexAttribPointer(m_vertexAttribIndex, 2, GL_FLOAT, GL_FALSE, 0, vertices); + glEnableVertexAttribArray(m_vertexAttribIndex); + glVertexAttribPointer(m_texCoordAttribIndex, 2, GL_FLOAT, GL_FALSE, 0, arrTextureCoords); + glEnableVertexAttribArray(m_texCoordAttribIndex); + } + glDrawArrays(GL_TRIANGLE_FAN, 0, 4); - glDisableVertexAttribArray(m_vertexAttribIndex); - glDisableVertexAttribArray(m_texCoordAttribIndex); + + if (m_vao) + { + m_vao->release(); + } + else + { + glDisableVertexAttribArray(m_vertexAttribIndex); + glDisableVertexAttribArray(m_texCoordAttribIndex); + } m_shader->release(); } diff --git a/sdrgui/gui/tvscreenanalog.h b/sdrgui/gui/tvscreenanalog.h index 3d1f6a2c3..fd78688d5 100644 --- a/sdrgui/gui/tvscreenanalog.h +++ b/sdrgui/gui/tvscreenanalog.h @@ -31,6 +31,8 @@ #include #include #include +#include +#include class TVScreenAnalogBuffer { @@ -130,6 +132,9 @@ class SDRGUI_API TVScreenAnalog : public QOpenGLWidget, protected QOpenGLFunctio TVScreenAnalogBuffer *m_backBuffer; QOpenGLShaderProgram *m_shader; + QOpenGLVertexArrayObject *m_vao; + QOpenGLBuffer *m_verticesBuf; + QOpenGLBuffer *m_textureCoordsBuf; QOpenGLTexture *m_imageTexture; QOpenGLTexture *m_lineShiftsTexture; From 8c500cf0c6ceee28e16bf2574e5bb5f3b4029916 Mon Sep 17 00:00:00 2001 From: Jon Beniston Date: Mon, 20 Jun 2022 08:50:28 +0100 Subject: [PATCH 12/12] Fix formatting --- sdrgui/gui/glshadersimple.cpp | 100 +++++++------- sdrgui/gui/glshadertextured.cpp | 230 ++++++++++++++++---------------- sdrgui/gui/glshadertextured.h | 40 +++--- 3 files changed, 185 insertions(+), 185 deletions(-) diff --git a/sdrgui/gui/glshadersimple.cpp b/sdrgui/gui/glshadersimple.cpp index f52c245da..6905682fd 100644 --- a/sdrgui/gui/glshadersimple.cpp +++ b/sdrgui/gui/glshadersimple.cpp @@ -26,22 +26,22 @@ #include "gui/glshadersimple.h" GLShaderSimple::GLShaderSimple() : - m_program(nullptr), + m_program(nullptr), m_vao(nullptr), m_verticesBuf(nullptr), m_vertexLoc(0), m_matrixLoc(0), - m_colorLoc(0) + m_colorLoc(0) { } GLShaderSimple::~GLShaderSimple() { - cleanup(); + cleanup(); } void GLShaderSimple::initializeGL(int majorVersion, int minorVersion) { - m_program = new QOpenGLShaderProgram; + m_program = new QOpenGLShaderProgram; if ((majorVersion > 3) || ((majorVersion == 3) && (minorVersion >= 3))) { @@ -66,16 +66,16 @@ void GLShaderSimple::initializeGL(int majorVersion, int minorVersion) } } - m_program->bindAttributeLocation("vertex", 0); + m_program->bindAttributeLocation("vertex", 0); - if (!m_program->link()) { - qDebug() << "GLShaderSimple::initializeGL: error linking shader: " << m_program->log(); - } + if (!m_program->link()) { + qDebug() << "GLShaderSimple::initializeGL: error linking shader: " << m_program->log(); + } - m_program->bind(); + m_program->bind(); m_vertexLoc = m_program->attributeLocation("vertex"); - m_matrixLoc = m_program->uniformLocation("uMatrix"); - m_colorLoc = m_program->uniformLocation("uColour"); + m_matrixLoc = m_program->uniformLocation("uMatrix"); + m_colorLoc = m_program->uniformLocation("uColour"); if (m_vao) { m_verticesBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); @@ -83,7 +83,7 @@ void GLShaderSimple::initializeGL(int majorVersion, int minorVersion) m_verticesBuf->create(); m_vao->release(); } - m_program->release(); + m_program->release(); } void GLShaderSimple::drawPoints(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents) @@ -93,30 +93,30 @@ void GLShaderSimple::drawPoints(const QMatrix4x4& transformMatrix, const QVector void GLShaderSimple::drawPolyline(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents) { - draw(GL_LINE_STRIP, transformMatrix, color, vertices, nbVertices, nbComponents); + draw(GL_LINE_STRIP, transformMatrix, color, vertices, nbVertices, nbComponents); } void GLShaderSimple::drawSegments(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents) { - draw(GL_LINES, transformMatrix, color, vertices, nbVertices, nbComponents); + draw(GL_LINES, transformMatrix, color, vertices, nbVertices, nbComponents); } void GLShaderSimple::drawContour(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents) { - draw(GL_LINE_LOOP, transformMatrix, color, vertices, nbVertices, nbComponents); + draw(GL_LINE_LOOP, transformMatrix, color, vertices, nbVertices, nbComponents); } void GLShaderSimple::drawSurface(const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents) { - draw(GL_TRIANGLE_FAN, transformMatrix, color, vertices, nbVertices, nbComponents); + draw(GL_TRIANGLE_FAN, transformMatrix, color, vertices, nbVertices, nbComponents); } void GLShaderSimple::draw(unsigned int mode, const QMatrix4x4& transformMatrix, const QVector4D& color, GLfloat *vertices, int nbVertices, int nbComponents) { - QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); - m_program->bind(); - m_program->setUniformValue(m_matrixLoc, transformMatrix); - m_program->setUniformValue(m_colorLoc, color); + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + m_program->bind(); + m_program->setUniformValue(m_matrixLoc, transformMatrix); + m_program->setUniformValue(m_colorLoc, color); if (m_vao) { m_vao->bind(); @@ -128,21 +128,21 @@ void GLShaderSimple::draw(unsigned int mode, const QMatrix4x4& transformMatrix, } else { - f->glEnableVertexAttribArray(m_vertexLoc); // vertex - f->glVertexAttribPointer(m_vertexLoc, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); + f->glEnableVertexAttribArray(m_vertexLoc); // vertex + f->glVertexAttribPointer(m_vertexLoc, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); } - f->glEnable(GL_BLEND); - f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - f->glLineWidth(1.0f); - f->glDrawArrays(mode, 0, nbVertices); + f->glEnable(GL_BLEND); + f->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + f->glLineWidth(1.0f); + f->glDrawArrays(mode, 0, nbVertices); if (m_vao) { m_vao->release(); } else { - f->glDisableVertexAttribArray(m_vertexLoc); + f->glDisableVertexAttribArray(m_vertexLoc); } - m_program->release(); + m_program->release(); } void GLShaderSimple::cleanup() @@ -156,34 +156,34 @@ void GLShaderSimple::cleanup() } const QString GLShaderSimple::m_vertexShaderSourceSimple2 = QString( - "uniform highp mat4 uMatrix;\n" - "attribute highp vec4 vertex;\n" - "void main() {\n" - " gl_Position = uMatrix * vertex;\n" - "}\n" - ); + "uniform highp mat4 uMatrix;\n" + "attribute highp vec4 vertex;\n" + "void main() {\n" + " gl_Position = uMatrix * vertex;\n" + "}\n" + ); const QString GLShaderSimple::m_vertexShaderSourceSimple = QString( "#version 330\n" - "uniform highp mat4 uMatrix;\n" - "in highp vec4 vertex;\n" - "void main() {\n" - " gl_Position = uMatrix * vertex;\n" - "}\n" - ); + "uniform highp mat4 uMatrix;\n" + "in highp vec4 vertex;\n" + "void main() {\n" + " gl_Position = uMatrix * vertex;\n" + "}\n" + ); const QString GLShaderSimple::m_fragmentShaderSourceColored2 = QString( - "uniform mediump vec4 uColour;\n" - "void main() {\n" - " gl_FragColor = uColour;\n" - "}\n" - ); + "uniform mediump vec4 uColour;\n" + "void main() {\n" + " gl_FragColor = uColour;\n" + "}\n" + ); const QString GLShaderSimple::m_fragmentShaderSourceColored = QString( "#version 330\n" "out vec4 fragColor;\n" - "uniform mediump vec4 uColour;\n" - "void main() {\n" - " fragColor = uColour;\n" - "}\n" - ); + "uniform mediump vec4 uColour;\n" + "void main() {\n" + " fragColor = uColour;\n" + "}\n" + ); diff --git a/sdrgui/gui/glshadertextured.cpp b/sdrgui/gui/glshadertextured.cpp index b9e2a4db0..07fc43a8c 100644 --- a/sdrgui/gui/glshadertextured.cpp +++ b/sdrgui/gui/glshadertextured.cpp @@ -27,22 +27,22 @@ #include "gui/glshadertextured.h" GLShaderTextured::GLShaderTextured() : - m_program(nullptr), + m_program(nullptr), m_vao(nullptr), m_verticesBuf(nullptr), m_textureCoordsBuf(nullptr), - m_texture(nullptr), + m_texture(nullptr), m_textureId(0), m_vertexLoc(0), m_texCoordLoc(0), - m_matrixLoc(0), - m_textureLoc(0), + m_matrixLoc(0), + m_textureLoc(0), m_useImmutableStorage(true) { } GLShaderTextured::~GLShaderTextured() { - cleanup(); + cleanup(); } void GLShaderTextured::initializeGL(int majorVersion, int minorVersion) @@ -75,18 +75,18 @@ void GLShaderTextured::initializeGL(int majorVersion, int minorVersion) } } - m_program->bindAttributeLocation("vertex", 0); - m_program->bindAttributeLocation("texCoord", 1); + m_program->bindAttributeLocation("vertex", 0); + m_program->bindAttributeLocation("texCoord", 1); - if (!m_program->link()) { - qDebug() << "GLShaderTextured::initializeGL: error linking shader: " << m_program->log(); - } + if (!m_program->link()) { + qDebug() << "GLShaderTextured::initializeGL: error linking shader: " << m_program->log(); + } - m_program->bind(); - m_vertexLoc = m_program->attributeLocation("vertex"); - m_texCoordLoc = m_program->attributeLocation("texCoord"); - m_matrixLoc = m_program->uniformLocation("uMatrix"); - m_textureLoc = m_program->uniformLocation("uTexture"); + m_program->bind(); + m_vertexLoc = m_program->attributeLocation("vertex"); + m_texCoordLoc = m_program->attributeLocation("texCoord"); + m_matrixLoc = m_program->uniformLocation("uMatrix"); + m_textureLoc = m_program->uniformLocation("uTexture"); if (m_vao) { m_verticesBuf = new QOpenGLBuffer(QOpenGLBuffer::VertexBuffer); @@ -97,7 +97,7 @@ void GLShaderTextured::initializeGL(int majorVersion, int minorVersion) m_textureCoordsBuf->create(); m_vao->release(); } - m_program->release(); + m_program->release(); } void GLShaderTextured::initTexture(const QImage& image, QOpenGLTexture::WrapMode wrapMode) @@ -111,34 +111,34 @@ void GLShaderTextured::initTexture(const QImage& image, QOpenGLTexture::WrapMode void GLShaderTextured::initTextureImmutable(const QImage& image, QOpenGLTexture::WrapMode wrapMode) { - if (m_texture) { - delete m_texture; - } + if (m_texture) { + delete m_texture; + } - m_texture = new QOpenGLTexture(image); + m_texture = new QOpenGLTexture(image); - m_texture->setMinificationFilter(QOpenGLTexture::Linear); - m_texture->setMagnificationFilter(QOpenGLTexture::Linear); - m_texture->setWrapMode(wrapMode); + m_texture->setMinificationFilter(QOpenGLTexture::Linear); + m_texture->setMagnificationFilter(QOpenGLTexture::Linear); + m_texture->setWrapMode(wrapMode); } void GLShaderTextured::initTextureMutable(const QImage& image, QOpenGLTexture::WrapMode wrapMode) { - if (m_textureId) + if (m_textureId) { - glDeleteTextures(1, &m_textureId); - m_textureId = 0; - } + glDeleteTextures(1, &m_textureId); + m_textureId = 0; + } - glGenTextures(1, &m_textureId); - glBindTexture(GL_TEXTURE_2D, m_textureId); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, - image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.constScanLine(0)); + glGenTextures(1, &m_textureId); + glBindTexture(GL_TEXTURE_2D, m_textureId); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, + image.width(), image.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, image.constScanLine(0)); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, wrapMode); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, wrapMode); } void GLShaderTextured::subTexture(int xOffset, int yOffset, int width, int height, const void *pixels) @@ -152,33 +152,33 @@ void GLShaderTextured::subTexture(int xOffset, int yOffset, int width, int heigh void GLShaderTextured::subTextureImmutable(int xOffset, int yOffset, int width, int height, const void *pixels) { - if (!m_texture) + if (!m_texture) { - qDebug("GLShaderTextured::subTextureImmutable: no texture defined. Doing nothing"); - return; - } + qDebug("GLShaderTextured::subTextureImmutable: no texture defined. Doing nothing"); + return; + } - QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); - m_texture->bind(); - f->glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + m_texture->bind(); + f->glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); } void GLShaderTextured::subTextureMutable(int xOffset, int yOffset, int width, int height, const void *pixels) { - if (!m_textureId) + if (!m_textureId) { - qDebug("GLShaderTextured::subTextureMutable: no texture defined. Doing nothing"); - return; - } + qDebug("GLShaderTextured::subTextureMutable: no texture defined. Doing nothing"); + return; + } - glBindTexture(GL_TEXTURE_2D, m_textureId); - glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); + glBindTexture(GL_TEXTURE_2D, m_textureId); + glTexSubImage2D(GL_TEXTURE_2D, 0, xOffset, yOffset, width, height, GL_RGBA, GL_UNSIGNED_BYTE, pixels); } void GLShaderTextured::drawSurface(const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices, int nbComponents) { if (m_useImmutableStorage) { - draw(GL_TRIANGLE_FAN, transformMatrix, textureCoords, vertices, nbVertices, nbComponents); + draw(GL_TRIANGLE_FAN, transformMatrix, textureCoords, vertices, nbVertices, nbComponents); } else { drawMutable(GL_TRIANGLE_FAN, transformMatrix, textureCoords, vertices, nbVertices, nbComponents); } @@ -186,17 +186,17 @@ void GLShaderTextured::drawSurface(const QMatrix4x4& transformMatrix, GLfloat *t void GLShaderTextured::draw(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices, int nbComponents) { - if (!m_texture) + if (!m_texture) { - qDebug("GLShaderTextured::draw: no texture defined. Doing nothing"); - return; - } + qDebug("GLShaderTextured::draw: no texture defined. Doing nothing"); + return; + } - QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); - m_program->bind(); - m_program->setUniformValue(m_matrixLoc, transformMatrix); - m_texture->bind(); - m_program->setUniformValue(m_textureLoc, 0); // Use texture unit 0 which magically contains our texture + QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions(); + m_program->bind(); + m_program->setUniformValue(m_matrixLoc, transformMatrix); + m_texture->bind(); + m_program->setUniformValue(m_textureLoc, 0); // Use texture unit 0 which magically contains our texture if (m_vao) { m_vao->bind(); @@ -213,13 +213,13 @@ void GLShaderTextured::draw(unsigned int mode, const QMatrix4x4& transformMatrix } else { - f->glEnableVertexAttribArray(m_vertexLoc); // vertex - f->glVertexAttribPointer(m_vertexLoc, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); - f->glEnableVertexAttribArray(m_texCoordLoc); // texture coordinates - f->glVertexAttribPointer(m_texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); + f->glEnableVertexAttribArray(m_vertexLoc); // vertex + f->glVertexAttribPointer(m_vertexLoc, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); + f->glEnableVertexAttribArray(m_texCoordLoc); // texture coordinates + f->glVertexAttribPointer(m_texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); } - f->glDrawArrays(mode, 0, nbVertices); + f->glDrawArrays(mode, 0, nbVertices); if (m_vao) { @@ -227,32 +227,32 @@ void GLShaderTextured::draw(unsigned int mode, const QMatrix4x4& transformMatrix } else { - f->glDisableVertexAttribArray(m_vertexLoc); - f->glDisableVertexAttribArray(m_texCoordLoc); + f->glDisableVertexAttribArray(m_vertexLoc); + f->glDisableVertexAttribArray(m_texCoordLoc); } - m_program->release(); + m_program->release(); } void GLShaderTextured::drawMutable(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices, int nbComponents) { - if (!m_textureId) + if (!m_textureId) { - qDebug("GLShaderTextured::drawMutable: no texture defined. Doing nothing"); - return; - } + qDebug("GLShaderTextured::drawMutable: no texture defined. Doing nothing"); + return; + } - m_program->bind(); - m_program->setUniformValue(m_matrixLoc, transformMatrix); - glBindTexture(GL_TEXTURE_2D, m_textureId); - m_program->setUniformValue(m_textureLoc, 0); // Use texture unit 0 which magically contains our texture - glEnableVertexAttribArray(m_vertexLoc); // vertex - glVertexAttribPointer(m_vertexLoc, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); - glEnableVertexAttribArray(m_texCoordLoc); // texture coordinates - glVertexAttribPointer(m_texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); - glDrawArrays(mode, 0, nbVertices); - glDisableVertexAttribArray(m_vertexLoc); - glDisableVertexAttribArray(m_texCoordLoc); - m_program->release(); + m_program->bind(); + m_program->setUniformValue(m_matrixLoc, transformMatrix); + glBindTexture(GL_TEXTURE_2D, m_textureId); + m_program->setUniformValue(m_textureLoc, 0); // Use texture unit 0 which magically contains our texture + glEnableVertexAttribArray(m_vertexLoc); // vertex + glVertexAttribPointer(m_vertexLoc, nbComponents, GL_FLOAT, GL_FALSE, 0, vertices); + glEnableVertexAttribArray(m_texCoordLoc); // texture coordinates + glVertexAttribPointer(m_texCoordLoc, 2, GL_FLOAT, GL_FALSE, 0, textureCoords); + glDrawArrays(mode, 0, nbVertices); + glDisableVertexAttribArray(m_vertexLoc); + glDisableVertexAttribArray(m_texCoordLoc); + m_program->release(); } void GLShaderTextured::cleanup() @@ -268,9 +268,9 @@ void GLShaderTextured::cleanup() delete m_texture; m_texture = nullptr; - if (!QOpenGLContext::currentContext()) { - return; - } + if (!QOpenGLContext::currentContext()) { + return; + } if (m_textureId) { @@ -307,42 +307,42 @@ bool GLShaderTextured::useImmutableStorage() } const QString GLShaderTextured::m_vertexShaderSourceTextured2 = QString( - "uniform highp mat4 uMatrix;\n" - "attribute highp vec4 vertex;\n" - "attribute highp vec2 texCoord;\n" - "varying mediump vec2 texCoordVar;\n" - "void main() {\n" - " gl_Position = uMatrix * vertex;\n" - " texCoordVar = texCoord;\n" - "}\n" - ); + "uniform highp mat4 uMatrix;\n" + "attribute highp vec4 vertex;\n" + "attribute highp vec2 texCoord;\n" + "varying mediump vec2 texCoordVar;\n" + "void main() {\n" + " gl_Position = uMatrix * vertex;\n" + " texCoordVar = texCoord;\n" + "}\n" + ); const QString GLShaderTextured::m_vertexShaderSourceTextured = QString( "#version 330\n" - "uniform highp mat4 uMatrix;\n" - "in highp vec4 vertex;\n" - "in highp vec2 texCoord;\n" - "out mediump vec2 texCoordVar;\n" - "void main() {\n" - " gl_Position = uMatrix * vertex;\n" - " texCoordVar = texCoord;\n" - "}\n" - ); + "uniform highp mat4 uMatrix;\n" + "in highp vec4 vertex;\n" + "in highp vec2 texCoord;\n" + "out mediump vec2 texCoordVar;\n" + "void main() {\n" + " gl_Position = uMatrix * vertex;\n" + " texCoordVar = texCoord;\n" + "}\n" + ); const QString GLShaderTextured::m_fragmentShaderSourceTextured2 = QString( - "uniform lowp sampler2D uTexture;\n" - "varying mediump vec2 texCoordVar;\n" - "void main() {\n" - " gl_FragColor = texture2D(uTexture, texCoordVar);\n" - "}\n" - ); + "uniform lowp sampler2D uTexture;\n" + "varying mediump vec2 texCoordVar;\n" + "void main() {\n" + " gl_FragColor = texture2D(uTexture, texCoordVar);\n" + "}\n" + ); const QString GLShaderTextured::m_fragmentShaderSourceTextured = QString( "#version 330\n" - "uniform lowp sampler2D uTexture;\n" - "in mediump vec2 texCoordVar;\n" + "uniform lowp sampler2D uTexture;\n" + "in mediump vec2 texCoordVar;\n" "out vec4 fragColor;\n" - "void main() {\n" - " fragColor = texture(uTexture, texCoordVar);\n" - "}\n" - ); + "void main() {\n" + " fragColor = texture(uTexture, texCoordVar);\n" + "}\n" + ); diff --git a/sdrgui/gui/glshadertextured.h b/sdrgui/gui/glshadertextured.h index a92b0d98e..f422716a0 100644 --- a/sdrgui/gui/glshadertextured.h +++ b/sdrgui/gui/glshadertextured.h @@ -37,39 +37,39 @@ class QImage; class SDRGUI_API GLShaderTextured : protected QOpenGLFunctions { public: - GLShaderTextured(); - ~GLShaderTextured(); + GLShaderTextured(); + ~GLShaderTextured(); - void initializeGL(int majorVersion, int minorVersion); - void initTexture(const QImage& image, QOpenGLTexture::WrapMode wrapMode = QOpenGLTexture::Repeat); - void subTexture(int xOffset, int yOffset, int width, int height, const void *pixels); - void drawSurface(const QMatrix4x4& transformMatrix, GLfloat* textureCoords, GLfloat *vertices, int nbVertices, int nbComponents=2); - void cleanup(); + void initializeGL(int majorVersion, int minorVersion); + void initTexture(const QImage& image, QOpenGLTexture::WrapMode wrapMode = QOpenGLTexture::Repeat); + void subTexture(int xOffset, int yOffset, int width, int height, const void *pixels); + void drawSurface(const QMatrix4x4& transformMatrix, GLfloat* textureCoords, GLfloat *vertices, int nbVertices, int nbComponents=2); + void cleanup(); private: - void draw(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices, int nbComponents); + void draw(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices, int nbComponents); void drawMutable(unsigned int mode, const QMatrix4x4& transformMatrix, GLfloat *textureCoords, GLfloat *vertices, int nbVertices, int nbComponents); - void initTextureImmutable(const QImage& image, QOpenGLTexture::WrapMode wrapMode = QOpenGLTexture::Repeat); - void subTextureImmutable(int xOffset, int yOffset, int width, int height, const void *pixels); - void initTextureMutable(const QImage& image, QOpenGLTexture::WrapMode wrapMode = QOpenGLTexture::Repeat); - void subTextureMutable(int xOffset, int yOffset, int width, int height, const void *pixels); + void initTextureImmutable(const QImage& image, QOpenGLTexture::WrapMode wrapMode = QOpenGLTexture::Repeat); + void subTextureImmutable(int xOffset, int yOffset, int width, int height, const void *pixels); + void initTextureMutable(const QImage& image, QOpenGLTexture::WrapMode wrapMode = QOpenGLTexture::Repeat); + void subTextureMutable(int xOffset, int yOffset, int width, int height, const void *pixels); bool useImmutableStorage(); - QOpenGLShaderProgram *m_program; + QOpenGLShaderProgram *m_program; QOpenGLVertexArrayObject *m_vao; QOpenGLBuffer *m_verticesBuf; QOpenGLBuffer *m_textureCoordsBuf; - QOpenGLTexture *m_texture; + QOpenGLTexture *m_texture; unsigned int m_textureId; int m_vertexLoc; int m_texCoordLoc; - int m_matrixLoc; - int m_textureLoc; + int m_matrixLoc; + int m_textureLoc; bool m_useImmutableStorage; - static const QString m_vertexShaderSourceTextured2; - static const QString m_vertexShaderSourceTextured; - static const QString m_fragmentShaderSourceTextured2; - static const QString m_fragmentShaderSourceTextured; + static const QString m_vertexShaderSourceTextured2; + static const QString m_vertexShaderSourceTextured; + static const QString m_fragmentShaderSourceTextured2; + static const QString m_fragmentShaderSourceTextured; }; #endif /* INCLUDE_GUI_GLSHADERTEXTURED_H_ */