Merge lp:~georg-zotti/stellarium/gz_milkyway-extinction into lp:stellarium

Proposed by Alexander Wolf
Status: Merged
Merged at revision: 7109
Proposed branch: lp:~georg-zotti/stellarium/gz_milkyway-extinction
Merge into: lp:stellarium
Diff against target: 1165 lines (+376/-105)
17 files modified
src/core/RefractionExtinction.hpp (+1/-1)
src/core/StelObject.cpp (+1/-1)
src/core/StelObject.hpp (+1/-1)
src/core/StelPainter.cpp (+200/-40)
src/core/StelPainter.hpp (+22/-7)
src/core/StelProjector.hpp (+1/-1)
src/core/StelSphereGeometry.cpp (+4/-2)
src/core/StelSphereGeometry.hpp (+1/-1)
src/core/StelUtils.cpp (+8/-12)
src/core/StelUtils.hpp (+1/-3)
src/core/StelVertexArray.cpp (+3/-1)
src/core/StelVertexArray.hpp (+61/-17)
src/core/modules/Landscape.cpp (+1/-1)
src/core/modules/MilkyWay.cpp (+68/-15)
src/core/modules/MilkyWay.hpp (+1/-1)
src/core/modules/Nebula.hpp (+1/-0)
src/gui/LocationDialog.hpp (+1/-1)
To merge this branch: bzr merge lp:~georg-zotti/stellarium/gz_milkyway-extinction
Reviewer Review Type Date Requested Status
gzotti Approve
Fabien Chéreau Needs Information
Alexander Wolf Approve
Review via email: mp+239766@code.launchpad.net

This proposal supersedes a proposal from 2014-10-17.

Description of the change

I finally managed to add extinction to the Milky Way (and other extended objects could have the same now.) I added some comments where the new items are, these will be cleaned up during merge. I had to change the Milky Way texture (now half the size without loss of function).

To post a comment you must log in.
Revision history for this message
Fabien Chéreau (xalioth) wrote : Posted in a previous version of this proposal
Download full text (53.1 KiB)

Hi, thanks for the contribution!
Somehow I'm a bit afraid by the large change and the impact on
performances...

I wonder if there is not a much simpler way more in line with the way
refraction was done, I.e. process extinction more at projection time by
passing the vertex color in the project function.

Fabien
Le 17 oct. 2014 16:29, "gzotti" <email address hidden> a écrit :

> gzotti has proposed merging
> lp:~georg-zotti/stellarium/gz_milkyway-extinction into lp:stellarium.
>
> Commit message:
> Extinction for Milky Way
>
> Requested reviews:
> Stellarium (stellarium)
>
> For more details, see:
>
> https://code.launchpad.net/~georg-zotti/stellarium/gz_milkyway-extinction/+merge/238721
>
> I finally managed to add extinction to the Milky Way (and other extended
> objects could have the same now.) I added some comments where the new items
> are, these will be cleaned up during merge. I had to change the Milky Way
> texture (now half the size without loss of function).
>
>
> --
>
> https://code.launchpad.net/~georg-zotti/stellarium/gz_milkyway-extinction/+merge/238721
> You are subscribed to branch lp:stellarium.
>
> === modified file 'src/core/RefractionExtinction.hpp'
> --- src/core/RefractionExtinction.hpp 2013-11-15 14:34:44 +0000
> +++ src/core/RefractionExtinction.hpp 2014-10-17 14:28:29 +0000
> @@ -45,7 +45,7 @@
> class Extinction
> {
> public:
> - //! Define the extinction strategy for rendering underground
> objects (usefull when ground is not rendered)
> + //! Define the extinction strategy for rendering underground
> objects (useful when ground is not rendered)
> enum UndergroundExtinctionMode {
> UndergroundExtinctionZero = 0, //!< Zero extinction:
> stars visible in full brightness
> UndergroundExtinctionMax = 1, //!< Maximum extinction:
> coef 42, i.e practically invisible
>
> === modified file 'src/core/StelCore.hpp'
> --- src/core/StelCore.hpp 2014-10-05 11:32:51 +0000
> +++ src/core/StelCore.hpp 2014-10-17 14:28:29 +0000
> @@ -198,6 +198,7 @@
> Vec3d altAzToJ2000(const Vec3d& v, RefractionMode
> refMode=RefractionAuto) const;
> Vec3d j2000ToAltAz(const Vec3d& v, RefractionMode
> refMode=RefractionAuto) const;
> void j2000ToAltAzInPlaceNoRefraction(Vec3f* v) const
> {v->transfo4d(matJ2000ToAltAz);}
> + void j2000ToAltAzInPlaceNoRefraction(Vec3d* v) const
> {v->transfo4d(matJ2000ToAltAz);} // GZ NEW for milky way
> Vec3d galacticToJ2000(const Vec3d& v) const;
> Vec3d equinoxEquToJ2000(const Vec3d& v) const;
> Vec3d j2000ToEquinoxEqu(const Vec3d& v) const;
>
> === modified file 'src/core/StelPainter.cpp'
> --- src/core/StelPainter.cpp 2014-06-06 04:26:56 +0000
> +++ src/core/StelPainter.cpp 2014-10-17 14:28:29 +0000
> @@ -699,7 +699,7 @@
> // Project the passed triangle on the screen ensuring that it will look
> smooth, even for non linear distortion
> // by splitting it into subtriangles.
> void StelPainter::projectSphericalTriangle(const SphericalCap*
> clippingCap, const Vec3d* vertices, QVarLengthArray<Vec3f, 4096>*
> outVertices,
> - const Vec2f* texturePos, QVarLengthAr...

Revision history for this message
Alexander Wolf (alexwolf) wrote : Posted in a previous version of this proposal

It's a very good feature! I checked the performance but this parameter not changed on my linux-box.

review: Approve
Revision history for this message
gzotti (georg-zotti) wrote : Posted in a previous version of this proposal

Fabien, do you mean in StelPainter::projectArray() or even prj->project()? At this step we need azimuthal coordinates, I don't see how I could extract those from this overall projection to viewport. Where can this be done?

The longest change in code was the required extension of StelPainter into actually being able to use vertex color arrays - the shader was already here, but StelVertexArray had no color array.

I had to increase Milky Way vertex density for better accuracy, but decreased overall spherical coverage by removing half of the texture (the black parts at the poles) and so also removed about half the required vertices.

I don't know how often update() is called. If less frequently than draw() but still every few frames, the extinction loop could also go there.

I will try to test equal setups of trunk vs. this for performance comparison.

Revision history for this message
Fabien Chéreau (xalioth) wrote : Posted in a previous version of this proposal

Well in fact you are right, there is no other easy way to deal with a color modulation, excepted maybe by computing the extinction directly in the vertex shader (by revert projecting the 2D vertices to get the original 3D vertex).

So the remaining comments are more minor ones:
 - please avoid to add // GZ in comments, it doesn't makes sense to the reader in the long term
 - please cleanup debug stuff
 - For simplicity I would also avoid the draw a ring but rather the full sphere with the higher resolution texture. We would really need a better 1024x512 milky way texture by the way. I do have one from mellinger that I re-processed that he allowed us to use. I'll send it to you by email.

Revision history for this message
gzotti (georg-zotti) wrote : Posted in a previous version of this proposal

OK. Settings: all default, debug builds. Today evening, Stereographic, 138°fov, FullHD, NVidia GTX580M.

Original trunk, 20x20 vertices, : 97fps. Atmosphere off: 108fps.

Milky Way with 72x18: 79fps
Milky Way with 48x15: 86fps
Milky Way with 45x15: 87fps
Milky Way with 40x15: 88fps (same. All figures went up/down by about +/- 1fps.)
Atmosphere off: 108fps
Putting the extinction loop in update(): no noticeable change (Is update called for every frame?)

So I think somewhere 40x15 should stay, if not better. This means a grid of 9x6 degrees, I would not want to go anywhere larger given the fast increase of extinction below 10 degrees. Yes, there is a penalty with the new function, but in the release builds I usually had almost 200fps, so I think there is ample reserve. But if there is a faster way, I don't see it, please show it to me.
Would it be useful to add a configuration option for this? I mean, extinction is one of the hi-quality features of this program, so it should be applied to all visible objects.

Revision history for this message
gzotti (georg-zotti) wrote : Posted in a previous version of this proposal

Most of the "GZs" are to be removed during merge. They are just to show where I have changed things or explain things to reviewers. Is it OK to remove MilkyWay.cpp:912ff, the original X/Y/Z rotations?

The texture resolution was only 512x512. Removing black parts leave 512x256. Replacing the sphere by the ring avoids about half of the vertices which are only black, so I do think this makes sense. But yes, a higher res drop-in replacement texture would be very welcome!

Revision history for this message
gzotti (georg-zotti) wrote : Posted in a previous version of this proposal

I think it looks fine now. Any further objections?

review: Needs Resubmitting
Revision history for this message
Alexander Wolf (alexwolf) wrote :

I think this branch ready for merge. Maybe here required some calibration for brightness of Milky Way, but it can be solved in trunk.

review: Approve
Revision history for this message
Fabien Chéreau (xalioth) wrote :

I'm still not quite fond of the ring trick as it will make it harder for people to change the milky way map, some people like to use other images such as infrared maps etc..

What about we keep it simple for now with a full sphere, and try to optimize the nominal code rather than this way?

Revision history for this message
Fabien Chéreau (xalioth) :
review: Needs Information
Revision history for this message
gzotti (georg-zotti) wrote :

Hu?

I am now using your new texture, and must therefore use a full sphere.
Although I would prefer the ring with a reprojected texture without poles.

G.

Revision history for this message
Fabien Chéreau (xalioth) wrote :

Ooops, I read too quickly. then in this case fine for me for merging,
thanks!

On Mon, Oct 27, 2014 at 10:30 PM, gzotti <email address hidden> wrote:

> Hu?
>
> I am now using your new texture, and must therefore use a full sphere.
> Although I would prefer the ring with a reprojected texture without poles.
>
> G.
>
>
> --
>
> https://code.launchpad.net/~georg-zotti/stellarium/gz_milkyway-extinction/+merge/239766
> You are reviewing the proposed merge of
> lp:~georg-zotti/stellarium/gz_milkyway-extinction into lp:stellarium.
>

Revision history for this message
gzotti (georg-zotti) wrote :

Of course I agree :-) I will cleanup some intermediate lines after merge.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/core/RefractionExtinction.hpp'
--- src/core/RefractionExtinction.hpp 2013-11-15 14:34:44 +0000
+++ src/core/RefractionExtinction.hpp 2014-10-27 19:13:24 +0000
@@ -45,7 +45,7 @@
45class Extinction45class Extinction
46{46{
47public:47public:
48 //! Define the extinction strategy for rendering underground objects (usefull when ground is not rendered)48 //! Define the extinction strategy for rendering underground objects (useful when ground is not rendered)
49 enum UndergroundExtinctionMode {49 enum UndergroundExtinctionMode {
50 UndergroundExtinctionZero = 0, //!< Zero extinction: stars visible in full brightness50 UndergroundExtinctionZero = 0, //!< Zero extinction: stars visible in full brightness
51 UndergroundExtinctionMax = 1, //!< Maximum extinction: coef 42, i.e practically invisible51 UndergroundExtinctionMax = 1, //!< Maximum extinction: coef 42, i.e practically invisible
5252
=== modified file 'src/core/StelObject.cpp'
--- src/core/StelObject.cpp 2014-10-26 11:18:06 +0000
+++ src/core/StelObject.cpp 2014-10-27 19:13:24 +0000
@@ -100,7 +100,7 @@
100 Vec3d altAzPos = getAltAzPosGeometric(core);100 Vec3d altAzPos = getAltAzPosGeometric(core);
101 altAzPos.normalize();101 altAzPos.normalize();
102 float vMag = getVMagnitude(core);102 float vMag = getVMagnitude(core);
103 // GZ 2014-01-02: without the test, planets flicker stupidly in fullsky atmosphere-less view.103 // without the test, planets flicker stupidly in fullsky atmosphere-less view.
104 if (core->getSkyDrawer()->getFlagHasAtmosphere())104 if (core->getSkyDrawer()->getFlagHasAtmosphere())
105 core->getSkyDrawer()->getExtinction().forward(altAzPos, &vMag);105 core->getSkyDrawer()->getExtinction().forward(altAzPos, &vMag);
106 return vMag;106 return vMag;
107107
=== modified file 'src/core/StelObject.hpp'
--- src/core/StelObject.hpp 2014-07-31 10:51:23 +0000
+++ src/core/StelObject.hpp 2014-10-27 19:13:24 +0000
@@ -134,7 +134,7 @@
134 virtual float getVMagnitude(const StelCore* core) const;134 virtual float getVMagnitude(const StelCore* core) const;
135 135
136 //! Return object's apparent V magnitude as seen from observer including extinction.136 //! Return object's apparent V magnitude as seen from observer including extinction.
137 //! GZ 2014-01-02: Extinction obviously only if atmosphere=on.137 //! Extinction obviously only if atmosphere=on.
138 float getVMagnitudeWithExtinction(const StelCore* core) const;138 float getVMagnitudeWithExtinction(const StelCore* core) const;
139139
140 //! Return a priority value which is used to discriminate objects by priority140 //! Return a priority value which is used to discriminate objects by priority
141141
=== modified file 'src/core/StelPainter.cpp'
--- src/core/StelPainter.cpp 2014-06-06 04:26:56 +0000
+++ src/core/StelPainter.cpp 2014-10-27 19:13:24 +0000
@@ -699,7 +699,7 @@
699// Project the passed triangle on the screen ensuring that it will look smooth, even for non linear distortion699// Project the passed triangle on the screen ensuring that it will look smooth, even for non linear distortion
700// by splitting it into subtriangles.700// by splitting it into subtriangles.
701void StelPainter::projectSphericalTriangle(const SphericalCap* clippingCap, const Vec3d* vertices, QVarLengthArray<Vec3f, 4096>* outVertices,701void StelPainter::projectSphericalTriangle(const SphericalCap* clippingCap, const Vec3d* vertices, QVarLengthArray<Vec3f, 4096>* outVertices,
702 const Vec2f* texturePos, QVarLengthArray<Vec2f, 4096>* outTexturePos,702 const Vec2f* texturePos, QVarLengthArray<Vec2f, 4096>* outTexturePos, const Vec3f *colors, QVarLengthArray<Vec3f, 4096> *outColors,
703 const double maxSqDistortion, const int nbI, const bool checkDisc1, const bool checkDisc2, const bool checkDisc3) const703 const double maxSqDistortion, const int nbI, const bool checkDisc1, const bool checkDisc2, const bool checkDisc3) const
704{704{
705 Q_ASSERT(fabs(vertices[0].length()-1.)<0.00001);705 Q_ASSERT(fabs(vertices[0].length()-1.)<0.00001);
@@ -758,6 +758,8 @@
758 outVertices->append(Vec3f(e0[0], e0[1], e0[2])); outVertices->append(Vec3f(e1[0], e1[1], e1[2])); outVertices->append(Vec3f(e2[0], e2[1], e2[2]));758 outVertices->append(Vec3f(e0[0], e0[1], e0[2])); outVertices->append(Vec3f(e1[0], e1[1], e1[2])); outVertices->append(Vec3f(e2[0], e2[1], e2[2]));
759 if (outTexturePos)759 if (outTexturePos)
760 outTexturePos->append(texturePos,3);760 outTexturePos->append(texturePos,3);
761 if (outColors)
762 outColors->append(colors,3);
761 return;763 return;
762 }764 }
763765
@@ -772,6 +774,8 @@
772 outVertices->append(Vec3f(e0[0], e0[1], e0[2])); outVertices->append(Vec3f(e1[0], e1[1], e2[2])); outVertices->append(Vec3f(e2[0], e2[1], e2[2]));774 outVertices->append(Vec3f(e0[0], e0[1], e0[2])); outVertices->append(Vec3f(e1[0], e1[1], e2[2])); outVertices->append(Vec3f(e2[0], e2[1], e2[2]));
773 if (outTexturePos)775 if (outTexturePos)
774 outTexturePos->append(texturePos,3);776 outTexturePos->append(texturePos,3);
777 if (outColors)
778 outColors->append(colors,3);
775 return;779 return;
776 }780 }
777781
@@ -779,6 +783,7 @@
779 // Depending on which combination of sides of the triangle has to be split a different strategy is used.783 // Depending on which combination of sides of the triangle has to be split a different strategy is used.
780 Vec3d va[3];784 Vec3d va[3];
781 Vec2f ta[3];785 Vec2f ta[3];
786 Vec3f ca[3];
782 // Only 1 side has to be split: split the triangle in 2787 // Only 1 side has to be split: split the triangle in 2
783 if (cDiscontinuity1 && !cDiscontinuity2 && !cDiscontinuity3)788 if (cDiscontinuity1 && !cDiscontinuity2 && !cDiscontinuity3)
784 {789 {
@@ -792,7 +797,13 @@
792 ta[1]=(texturePos[0]+texturePos[1])*0.5;797 ta[1]=(texturePos[0]+texturePos[1])*0.5;
793 ta[2]=texturePos[2];798 ta[2]=texturePos[2];
794 }799 }
795 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, true, true, false);800 if (outColors)
801 {
802 ca[0]=colors[0];
803 ca[1]=(colors[0]+colors[1])*0.5;
804 ca[2]=colors[2];
805 }
806 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, true, true, false);
796807
797 //va[0]=vertices[0]+vertices[1];808 //va[0]=vertices[0]+vertices[1];
798 //va[0].normalize();809 //va[0].normalize();
@@ -805,7 +816,13 @@
805 ta[1]=texturePos[1];816 ta[1]=texturePos[1];
806 ta[2]=texturePos[2];817 ta[2]=texturePos[2];
807 }818 }
808 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, true, false, true);819 if (outColors)
820 {
821 ca[0]=(colors[0]+colors[1])*0.5;
822 ca[1]=colors[1];
823 ca[2]=colors[2];
824 }
825 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, true, false, true);
809 return;826 return;
810 }827 }
811828
@@ -821,7 +838,13 @@
821 ta[1]=texturePos[1];838 ta[1]=texturePos[1];
822 ta[2]=(texturePos[1]+texturePos[2])*0.5;839 ta[2]=(texturePos[1]+texturePos[2])*0.5;
823 }840 }
824 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, false, true, true);841 if (outColors)
842 {
843 ca[0]=colors[0];
844 ca[1]=colors[1];
845 ca[2]=(colors[1]+colors[2])*0.5;
846 }
847 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, false, true, true);
825848
826 va[0]=vertices[0];849 va[0]=vertices[0];
827 //va[1]=vertices[1]+vertices[2];850 //va[1]=vertices[1]+vertices[2];
@@ -834,7 +857,13 @@
834 ta[1]=(texturePos[1]+texturePos[2])*0.5;857 ta[1]=(texturePos[1]+texturePos[2])*0.5;
835 ta[2]=texturePos[2];858 ta[2]=texturePos[2];
836 }859 }
837 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, true, true, false);860 if (outColors)
861 {
862 ca[0]=colors[0];
863 ca[1]=(colors[1]+colors[2])*0.5;
864 ca[2]=colors[2];
865 }
866 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, true, true, false);
838 return;867 return;
839 }868 }
840869
@@ -850,7 +879,13 @@
850 ta[1]=texturePos[1];879 ta[1]=texturePos[1];
851 ta[2]=(texturePos[0]+texturePos[2])*0.5;880 ta[2]=(texturePos[0]+texturePos[2])*0.5;
852 }881 }
853 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, false, true, true);882 if (outColors)
883 {
884 ca[0]=colors[0];
885 ca[1]=colors[1];
886 ca[2]=(colors[0]+colors[2])*0.5;
887 }
888 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, false, true, true);
854889
855 //va[0]=vertices[0]+vertices[2];890 //va[0]=vertices[0]+vertices[2];
856 //va[0].normalize();891 //va[0].normalize();
@@ -863,7 +898,13 @@
863 ta[1]=texturePos[1];898 ta[1]=texturePos[1];
864 ta[2]=texturePos[2];899 ta[2]=texturePos[2];
865 }900 }
866 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, true, false, true);901 if (outColors)
902 {
903 ca[0]=(colors[0]+colors[2])*0.5;
904 ca[1]=colors[1];
905 ca[2]=colors[2];
906 }
907 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, true, false, true);
867 return;908 return;
868 }909 }
869910
@@ -881,7 +922,13 @@
881 ta[1]=(texturePos[0]+texturePos[1])*0.5;922 ta[1]=(texturePos[0]+texturePos[1])*0.5;
882 ta[2]=(texturePos[1]+texturePos[2])*0.5;923 ta[2]=(texturePos[1]+texturePos[2])*0.5;
883 }924 }
884 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);925 if (outColors)
926 {
927 ca[0]=colors[0];
928 ca[1]=(colors[0]+colors[1])*0.5;
929 ca[2]=(colors[1]+colors[2])*0.5;
930 }
931 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
885932
886 //va[0]=vertices[0]+vertices[1];933 //va[0]=vertices[0]+vertices[1];
887 //va[0].normalize();934 //va[0].normalize();
@@ -895,7 +942,13 @@
895 ta[1]=texturePos[1];942 ta[1]=texturePos[1];
896 ta[2]=(texturePos[1]+texturePos[2])*0.5;943 ta[2]=(texturePos[1]+texturePos[2])*0.5;
897 }944 }
898 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);945 if (outColors)
946 {
947 ca[0]=(colors[0]+colors[1])*0.5;
948 ca[1]=colors[1];
949 ca[2]=(colors[1]+colors[2])*0.5;
950 }
951 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
899952
900 va[0]=vertices[0];953 va[0]=vertices[0];
901 //va[1]=vertices[1]+vertices[2];954 //va[1]=vertices[1]+vertices[2];
@@ -908,7 +961,13 @@
908 ta[1]=(texturePos[1]+texturePos[2])*0.5;961 ta[1]=(texturePos[1]+texturePos[2])*0.5;
909 ta[2]=texturePos[2];962 ta[2]=texturePos[2];
910 }963 }
911 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, true, true, false);964 if (outColors)
965 {
966 ca[0]=colors[0];
967 ca[1]=(colors[1]+colors[2])*0.5;
968 ca[2]=colors[2];
969 }
970 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, true, true, false);
912 return;971 return;
913 }972 }
914 if (cDiscontinuity1 && !cDiscontinuity2 && cDiscontinuity3)973 if (cDiscontinuity1 && !cDiscontinuity2 && cDiscontinuity3)
@@ -924,7 +983,13 @@
924 ta[1]=(texturePos[0]+texturePos[1])*0.5;983 ta[1]=(texturePos[0]+texturePos[1])*0.5;
925 ta[2]=(texturePos[0]+texturePos[2])*0.5;984 ta[2]=(texturePos[0]+texturePos[2])*0.5;
926 }985 }
927 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);986 if (outColors)
987 {
988 ca[0]=colors[0];
989 ca[1]=(colors[0]+colors[1])*0.5;
990 ca[2]=(colors[0]+colors[2])*0.5;
991 }
992 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
928993
929 //va[0]=vertices[0]+vertices[1];994 //va[0]=vertices[0]+vertices[1];
930 //va[0].normalize();995 //va[0].normalize();
@@ -938,7 +1003,13 @@
938 ta[1]=texturePos[2];1003 ta[1]=texturePos[2];
939 ta[2]=(texturePos[0]+texturePos[2])*0.5;1004 ta[2]=(texturePos[0]+texturePos[2])*0.5;
940 }1005 }
941 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);1006 if (outColors)
1007 {
1008 ca[0]=(colors[0]+colors[1])*0.5;
1009 ca[1]=colors[2];
1010 ca[2]=(colors[0]+colors[2])*0.5;
1011 }
1012 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
9421013
9431014
944 //va[0]=vertices[0]+vertices[1];1015 //va[0]=vertices[0]+vertices[1];
@@ -951,7 +1022,13 @@
951 ta[1]=texturePos[1];1022 ta[1]=texturePos[1];
952 ta[2]=texturePos[2];1023 ta[2]=texturePos[2];
953 }1024 }
954 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, true, false, true);1025 if (outColors)
1026 {
1027 ca[0]=(colors[0]+colors[1])*0.5;
1028 ca[1]=colors[1];
1029 ca[2]=colors[2];
1030 }
1031 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, true, false, true);
9551032
956 return;1033 return;
957 }1034 }
@@ -967,7 +1044,13 @@
967 ta[1]=texturePos[1];1044 ta[1]=texturePos[1];
968 ta[2]=(texturePos[1]+texturePos[2])*0.5;1045 ta[2]=(texturePos[1]+texturePos[2])*0.5;
969 }1046 }
970 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1, false, true, true);1047 if (outColors)
1048 {
1049 ca[0]=colors[0];
1050 ca[1]=colors[1];
1051 ca[2]=(colors[1]+colors[2])*0.5;
1052 }
1053 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1, false, true, true);
9711054
972 //va[0]=vertices[1]+vertices[2];1055 //va[0]=vertices[1]+vertices[2];
973 //va[0].normalize();1056 //va[0].normalize();
@@ -981,7 +1064,13 @@
981 ta[1]=texturePos[2];1064 ta[1]=texturePos[2];
982 ta[2]=(texturePos[0]+texturePos[2])*0.5;1065 ta[2]=(texturePos[0]+texturePos[2])*0.5;
983 }1066 }
984 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);1067 if (outColors)
1068 {
1069 ca[0]=(colors[1]+colors[2])*0.5;
1070 ca[1]=colors[2];
1071 ca[2]=(colors[0]+colors[2])*0.5;
1072 }
1073 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
9851074
986 va[1]=va[0];1075 va[1]=va[0];
987 va[0]=vertices[0];1076 va[0]=vertices[0];
@@ -995,7 +1084,13 @@
995 ta[1]=(texturePos[1]+texturePos[2])*0.5;1084 ta[1]=(texturePos[1]+texturePos[2])*0.5;
996 ta[2]=(texturePos[0]+texturePos[2])*0.5;1085 ta[2]=(texturePos[0]+texturePos[2])*0.5;
997 }1086 }
998 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);1087 if (outColors)
1088 {
1089 ca[0]=colors[0];
1090 ca[1]=(colors[1]+colors[2])*0.5;
1091 ca[2]=(colors[0]+colors[2])*0.5;
1092 }
1093 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
999 return;1094 return;
1000 }1095 }
10011096
@@ -1012,7 +1107,13 @@
1012 ta[1]=(texturePos[1]+texturePos[2])*0.5;1107 ta[1]=(texturePos[1]+texturePos[2])*0.5;
1013 ta[2]=(texturePos[0]+texturePos[2])*0.5;1108 ta[2]=(texturePos[0]+texturePos[2])*0.5;
1014 }1109 }
1015 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);1110 if (outColors)
1111 {
1112 ca[0]=(colors[0]+colors[1])*0.5;
1113 ca[1]=(colors[1]+colors[2])*0.5;
1114 ca[2]=(colors[0]+colors[2])*0.5;
1115 }
1116 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
10161117
1017 va[1]=va[0];1118 va[1]=va[0];
1018 va[0]=vertices[0];1119 va[0]=vertices[0];
@@ -1026,7 +1127,13 @@
1026 ta[1]=(texturePos[0]+texturePos[1])*0.5;1127 ta[1]=(texturePos[0]+texturePos[1])*0.5;
1027 ta[2]=(texturePos[0]+texturePos[2])*0.5;1128 ta[2]=(texturePos[0]+texturePos[2])*0.5;
1028 }1129 }
1029 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);1130 if (outColors)
1131 {
1132 ca[0]=colors[0];
1133 ca[1]=(colors[0]+colors[1])*0.5;
1134 ca[2]=(colors[0]+colors[2])*0.5;
1135 }
1136 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
10301137
1031 //va[0]=vertices[0]+vertices[1];1138 //va[0]=vertices[0]+vertices[1];
1032 //va[0].normalize();1139 //va[0].normalize();
@@ -1040,7 +1147,13 @@
1040 ta[1]=texturePos[1];1147 ta[1]=texturePos[1];
1041 ta[2]=(texturePos[1]+texturePos[2])*0.5;1148 ta[2]=(texturePos[1]+texturePos[2])*0.5;
1042 }1149 }
1043 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);1150 if (outColors)
1151 {
1152 ca[0]=(colors[0]+colors[1])*0.5;
1153 ca[1]=colors[1];
1154 ca[2]=(colors[1]+colors[2])*0.5;
1155 }
1156 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
10441157
1045 va[0]=vertices[0];va[0]+=vertices[2];1158 va[0]=vertices[0];va[0]+=vertices[2];
1046 va[0].normalize();1159 va[0].normalize();
@@ -1054,13 +1167,20 @@
1054 ta[1]=(texturePos[1]+texturePos[2])*0.5;1167 ta[1]=(texturePos[1]+texturePos[2])*0.5;
1055 ta[2]=texturePos[2];1168 ta[2]=texturePos[2];
1056 }1169 }
1057 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, maxSqDistortion, nbI+1);1170 if (outColors)
1171 {
1172 ca[0]=(colors[0]+colors[2])*0.5;
1173 ca[1]=(colors[1]+colors[2])*0.5;
1174 ca[2]=colors[2];
1175 }
1176 projectSphericalTriangle(clippingCap, va, outVertices, ta, outTexturePos, ca, outColors, maxSqDistortion, nbI+1);
10581177
1059 return;1178 return;
1060}1179}
10611180
1062static QVarLengthArray<Vec3f, 4096> polygonVertexArray;1181static QVarLengthArray<Vec3f, 4096> polygonVertexArray;
1063static QVarLengthArray<Vec2f, 4096> polygonTextureCoordArray;1182static QVarLengthArray<Vec2f, 4096> polygonTextureCoordArray;
1183static QVarLengthArray<Vec3f, 4096> polygonColorArray;
1064static QVarLengthArray<unsigned int, 4096> indexArray;1184static QVarLengthArray<unsigned int, 4096> indexArray;
10651185
1066void StelPainter::drawGreatCircleArcs(const StelVertexArray& va, const SphericalCap* clippingCap)1186void StelPainter::drawGreatCircleArcs(const StelVertexArray& va, const SphericalCap* clippingCap)
@@ -1097,26 +1217,38 @@
1097{1217{
1098public:1218public:
1099 VertexArrayProjector(const StelVertexArray& ar, StelPainter* apainter, const SphericalCap* aclippingCap,1219 VertexArrayProjector(const StelVertexArray& ar, StelPainter* apainter, const SphericalCap* aclippingCap,
1100 QVarLengthArray<Vec3f, 4096>* aoutVertices, QVarLengthArray<Vec2f, 4096>* aoutTexturePos=NULL, double amaxSqDistortion=5.)1220 QVarLengthArray<Vec3f, 4096>* aoutVertices, QVarLengthArray<Vec2f, 4096>* aoutTexturePos=NULL, QVarLengthArray<Vec3f, 4096>* aoutColors=NULL, double amaxSqDistortion=5.)
1101 : vertexArray(ar), painter(apainter), clippingCap(aclippingCap), outVertices(aoutVertices),1221 : vertexArray(ar), painter(apainter), clippingCap(aclippingCap), outVertices(aoutVertices),
1102 outTexturePos(aoutTexturePos), maxSqDistortion(amaxSqDistortion)1222 outColors(aoutColors), outTexturePos(aoutTexturePos), maxSqDistortion(amaxSqDistortion)
1103 {1223 {
1104 }1224 }
11051225
1106 // Project a single triangle and add it into the output arrays1226 // Project a single triangle and add it into the output arrays
1107 inline void operator()(const Vec3d* v0, const Vec3d* v1, const Vec3d* v2,1227 inline void operator()(const Vec3d* v0, const Vec3d* v1, const Vec3d* v2,
1108 const Vec2f* t0, const Vec2f* t1, const Vec2f* t2,1228 const Vec2f* t0, const Vec2f* t1, const Vec2f* t2,
1229 const Vec3f* c0, const Vec3f* c1, const Vec3f* c2,
1109 unsigned int, unsigned int, unsigned)1230 unsigned int, unsigned int, unsigned)
1110 {1231 {
1111 // XXX: we may optimize more by putting the declaration and the test outside of this method.1232 // XXX: we may optimize more by putting the declaration and the test outside of this method.
1112 const Vec3d tmpVertex[3] = {*v0, *v1, *v2};1233 const Vec3d tmpVertex[3] = {*v0, *v1, *v2};
1113 if (outTexturePos)1234 if ( (outTexturePos) && (outColors))
1114 {1235 {
1115 const Vec2f tmpTexture[3] = {*t0, *t1, *t2};1236 const Vec2f tmpTexture[3] = {*t0, *t1, *t2};
1116 painter->projectSphericalTriangle(clippingCap, tmpVertex, outVertices, tmpTexture, outTexturePos, maxSqDistortion);1237 const Vec3f tmpColor[3] = {*c0, *c1, *c2};
1238 painter->projectSphericalTriangle(clippingCap, tmpVertex, outVertices, tmpTexture, outTexturePos, tmpColor, outColors, maxSqDistortion);
1239 }
1240 else if (outTexturePos)
1241 {
1242 const Vec2f tmpTexture[3] = {*t0, *t1, *t2};
1243 painter->projectSphericalTriangle(clippingCap, tmpVertex, outVertices, tmpTexture, outTexturePos, NULL, NULL, maxSqDistortion);
1244 }
1245 else if (outColors)
1246 {
1247 const Vec3f tmpColor[3] = {*c0, *c1, *c2};
1248 painter->projectSphericalTriangle(clippingCap, tmpVertex, outVertices, NULL, NULL, tmpColor, outColors, maxSqDistortion);
1117 }1249 }
1118 else1250 else
1119 painter->projectSphericalTriangle(clippingCap, tmpVertex, outVertices, NULL, NULL, maxSqDistortion);1251 painter->projectSphericalTriangle(clippingCap, tmpVertex, outVertices, NULL, NULL, NULL, NULL, maxSqDistortion);
1120 }1252 }
11211253
1122 // Draw the resulting arrays1254 // Draw the resulting arrays
@@ -1125,7 +1257,10 @@
1125 painter->setVertexPointer(3, GL_FLOAT, outVertices->constData());1257 painter->setVertexPointer(3, GL_FLOAT, outVertices->constData());
1126 if (outTexturePos)1258 if (outTexturePos)
1127 painter->setTexCoordPointer(2, GL_FLOAT, outTexturePos->constData());1259 painter->setTexCoordPointer(2, GL_FLOAT, outTexturePos->constData());
1128 painter->enableClientStates(true, outTexturePos != NULL);1260 if (outColors)
1261 painter->setColorPointer(3, GL_FLOAT, outColors->constData());
1262
1263 painter->enableClientStates(true, outTexturePos != NULL, outColors != NULL);
1129 painter->drawFromArray(StelPainter::Triangles, outVertices->size(), 0, false);1264 painter->drawFromArray(StelPainter::Triangles, outVertices->size(), 0, false);
1130 painter->enableClientStates(false);1265 painter->enableClientStates(false);
1131 }1266 }
@@ -1135,6 +1270,7 @@
1135 StelPainter* painter;1270 StelPainter* painter;
1136 const SphericalCap* clippingCap;1271 const SphericalCap* clippingCap;
1137 QVarLengthArray<Vec3f, 4096>* outVertices;1272 QVarLengthArray<Vec3f, 4096>* outVertices;
1273 QVarLengthArray<Vec3f, 4096>* outColors;
1138 QVarLengthArray<Vec2f, 4096>* outTexturePos;1274 QVarLengthArray<Vec2f, 4096>* outTexturePos;
1139 double maxSqDistortion;1275 double maxSqDistortion;
1140};1276};
@@ -1152,11 +1288,23 @@
1152 if (arr.isTextured())1288 if (arr.isTextured())
1153 {1289 {
1154 setTexCoordPointer(2, GL_FLOAT, arr.texCoords.constData());1290 setTexCoordPointer(2, GL_FLOAT, arr.texCoords.constData());
1155 enableClientStates(true, true);1291 if (arr.isColored())
1292 {
1293 setColorPointer(3, GL_FLOAT, arr.colors.constData());
1294 enableClientStates(true, true, true);
1295 }
1296 else
1297 enableClientStates(true, true, false);
1156 }1298 }
1157 else1299 else
1158 {1300 {
1159 enableClientStates(true, false);1301 if (arr.isColored())
1302 {
1303 setColorPointer(3, GL_FLOAT, arr.colors.constData());
1304 enableClientStates(true, false, true);
1305 }
1306 else
1307 enableClientStates(true, false, false);
1160 }1308 }
1161 if (arr.isIndexed())1309 if (arr.isIndexed())
1162 drawFromArray((StelPainter::DrawingMode)arr.primitiveType, arr.indices.size(), 0, true, arr.indices.constData());1310 drawFromArray((StelPainter::DrawingMode)arr.primitiveType, arr.indices.size(), 0, true, arr.indices.constData());
@@ -1166,7 +1314,7 @@
1166 enableClientStates(false);1314 enableClientStates(false);
1167}1315}
11681316
1169void StelPainter::drawSphericalTriangles(const StelVertexArray& va, const bool textured, const SphericalCap* clippingCap, const bool doSubDivide, const double maxSqDistortion)1317void StelPainter::drawSphericalTriangles(const StelVertexArray& va, const bool textured, const bool colored, const SphericalCap* clippingCap, const bool doSubDivide, const double maxSqDistortion)
1170{1318{
1171 if (va.vertex.isEmpty())1319 if (va.vertex.isEmpty())
1172 return;1320 return;
@@ -1174,6 +1322,7 @@
1174 Q_ASSERT(va.vertex.size()>2);1322 Q_ASSERT(va.vertex.size()>2);
1175 polygonVertexArray.clear();1323 polygonVertexArray.clear();
1176 polygonTextureCoordArray.clear();1324 polygonTextureCoordArray.clear();
1325
1177 indexArray.clear();1326 indexArray.clear();
11781327
1179 if (!doSubDivide)1328 if (!doSubDivide)
@@ -1186,7 +1335,7 @@
1186 // the last case. It is the slowest, it process the triangles one by one.1335 // the last case. It is the slowest, it process the triangles one by one.
1187 {1336 {
1188 // Project all the triangles of the VertexArray into our buffer arrays.1337 // Project all the triangles of the VertexArray into our buffer arrays.
1189 VertexArrayProjector result = va.foreachTriangle(VertexArrayProjector(va, this, clippingCap, &polygonVertexArray, textured ? &polygonTextureCoordArray : NULL, maxSqDistortion));1338 VertexArrayProjector result = va.foreachTriangle(VertexArrayProjector(va, this, clippingCap, &polygonVertexArray, textured ? &polygonTextureCoordArray : NULL, colored ? &polygonColorArray : NULL, maxSqDistortion));
1190 result.drawResult();1339 result.drawResult();
1191 return;1340 return;
1192 }1341 }
@@ -1211,7 +1360,8 @@
1211 glEnable(GL_CULL_FACE);1360 glEnable(GL_CULL_FACE);
1212 // The polygon is already tesselated as triangles1361 // The polygon is already tesselated as triangles
1213 if (doSubDivise || prj->intersectViewportDiscontinuity(poly->getBoundingCap()))1362 if (doSubDivise || prj->intersectViewportDiscontinuity(poly->getBoundingCap()))
1214 drawSphericalTriangles(poly->getFillVertexArray(), drawMode==SphericalPolygonDrawModeTextureFill, clippingCap, doSubDivise, maxSqDistortion);1363 // flag for color-modulated textured mode (e.g. for Milky Way/extincted)
1364 drawSphericalTriangles(poly->getFillVertexArray(), drawMode>=SphericalPolygonDrawModeTextureFill, drawMode==SphericalPolygonDrawModeTextureFillColormodulated, clippingCap, doSubDivise, maxSqDistortion);
1215 else1365 else
1216 drawStelVertexArray(poly->getFillVertexArray(), false);1366 drawStelVertexArray(poly->getFillVertexArray(), false);
12171367
@@ -1373,7 +1523,7 @@
13731523
1374///////////////////////////////////////////////////////////////////////////1524///////////////////////////////////////////////////////////////////////////
1375// Drawing methods for general (non-linear) mode.1525// Drawing methods for general (non-linear) mode.
1376// GZ This used to draw a full sphere. Now it's possible to have a spherical zone only.1526// This used to draw a full sphere. Since 0.13 it's possible to have a spherical zone only.
1377void StelPainter::sSphere(const float radius, const float oneMinusOblateness, const int slices, const int stacks, const int orientInside, const bool flipTexture, const float topAngle, const float bottomAngle)1527void StelPainter::sSphere(const float radius, const float oneMinusOblateness, const int slices, const int stacks, const int orientInside, const bool flipTexture, const float topAngle, const float bottomAngle)
1378{1528{
1379 GLfloat x, y, z;1529 GLfloat x, y, z;
@@ -1394,14 +1544,14 @@
13941544
1395 const float* cos_sin_rho = NULL;1545 const float* cos_sin_rho = NULL;
1396 Q_ASSERT(topAngle<bottomAngle); // don't forget: These are opening angles counted from top.1546 Q_ASSERT(topAngle<bottomAngle); // don't forget: These are opening angles counted from top.
1397 if ((bottomAngle>3.1415) && (topAngle<0.0001)) // safety margin.1547 if ((bottomAngle>3.1415f) && (topAngle<0.0001f)) // safety margin.
1398 cos_sin_rho = StelUtils::ComputeCosSinRho(stacks);1548 cos_sin_rho = StelUtils::ComputeCosSinRho(stacks);
1399 else1549 else
1400 {1550 {
1401 const float drho = (bottomAngle-topAngle) / stacks; // deltaRho: originally just 180degrees/stacks, now the range clamped.1551 const float drho = (bottomAngle-topAngle) / stacks; // deltaRho: originally just 180degrees/stacks, now the range clamped.
1402 cos_sin_rho = StelUtils::ComputeCosSinRhoZone(drho, stacks, M_PI-bottomAngle);1552 cos_sin_rho = StelUtils::ComputeCosSinRhoZone(drho, stacks, M_PI-bottomAngle);
1403 }1553 }
1404 // GZ: Allow parameters so that pole regions may remain free.1554 // Allow parameters so that pole regions may remain free.
1405 const float* cos_sin_rho_p;1555 const float* cos_sin_rho_p;
14061556
1407 const float* cos_sin_theta = StelUtils::ComputeCosSinTheta(slices);1557 const float* cos_sin_theta = StelUtils::ComputeCosSinTheta(slices);
@@ -1414,7 +1564,7 @@
1414 const GLfloat ds = (flipTexture ? -1.f : 1.f) / slices;1564 const GLfloat ds = (flipTexture ? -1.f : 1.f) / slices;
1415 const GLfloat dt = nsign / stacks; // from inside texture is reversed1565 const GLfloat dt = nsign / stacks; // from inside texture is reversed
14161566
1417 // draw intermediate as quad strips1567 // draw intermediate as quad strips
1418 static QVector<double> vertexArr;1568 static QVector<double> vertexArr;
1419 static QVector<float> texCoordArr;1569 static QVector<float> texCoordArr;
1420 static QVector<float> colorArr;1570 static QVector<float> colorArr;
@@ -1456,7 +1606,8 @@
1456 drawFromArray(Triangles, indiceArr.size(), 0, true, indiceArr.constData());1606 drawFromArray(Triangles, indiceArr.size(), 0, true, indiceArr.constData());
1457}1607}
14581608
1459StelVertexArray StelPainter::computeSphereNoLight(const float radius, const float oneMinusOblateness, const int slices, const int stacks, const int orientInside, const bool flipTexture)1609StelVertexArray StelPainter::computeSphereNoLight(const float radius, const float oneMinusOblateness, const int slices, const int stacks,
1610 const int orientInside, const bool flipTexture, const float topAngle, const float bottomAngle)
1460{1611{
1461 StelVertexArray result(StelVertexArray::Triangles);1612 StelVertexArray result(StelVertexArray::Triangles);
1462 GLfloat x, y, z;1613 GLfloat x, y, z;
@@ -1474,7 +1625,16 @@
1474 t=1.f;1625 t=1.f;
1475 }1626 }
14761627
1477 const float* cos_sin_rho = StelUtils::ComputeCosSinRho(stacks);1628 const float* cos_sin_rho = NULL; //StelUtils::ComputeCosSinRho(stacks);
1629 Q_ASSERT(topAngle<bottomAngle); // don't forget: These are opening angles counted from top.
1630 if ((bottomAngle>3.1415f) && (topAngle<0.0001f)) // safety margin.
1631 cos_sin_rho = StelUtils::ComputeCosSinRho(stacks);
1632 else
1633 {
1634 const float drho = (bottomAngle-topAngle) / stacks; // deltaRho: originally just 180degrees/stacks, now the range clamped.
1635 cos_sin_rho = StelUtils::ComputeCosSinRhoZone(drho, stacks, M_PI-bottomAngle);
1636 }
1637 // Allow parameters so that pole regions may remain free.
1478 const float* cos_sin_rho_p;1638 const float* cos_sin_rho_p;
14791639
1480 const float* cos_sin_theta = StelUtils::ComputeCosSinTheta(slices);1640 const float* cos_sin_theta = StelUtils::ComputeCosSinTheta(slices);
@@ -1487,7 +1647,7 @@
1487 const GLfloat ds = (flipTexture ? -1.f : 1.f) / slices;1647 const GLfloat ds = (flipTexture ? -1.f : 1.f) / slices;
1488 const GLfloat dt = nsign / stacks; // from inside texture is reversed1648 const GLfloat dt = nsign / stacks; // from inside texture is reversed
14891649
1490 // draw intermediate as quad strips1650 // draw intermediate as quad strips
1491 for (i = 0,cos_sin_rho_p = cos_sin_rho; i < stacks; ++i,cos_sin_rho_p+=2)1651 for (i = 0,cos_sin_rho_p = cos_sin_rho; i < stacks; ++i,cos_sin_rho_p+=2)
1492 {1652 {
1493 s = !flipTexture ? 0.f : 1.f;1653 s = !flipTexture ? 0.f : 1.f;
14941654
=== modified file 'src/core/StelPainter.hpp'
--- src/core/StelPainter.hpp 2014-06-10 19:20:20 +0000
+++ src/core/StelPainter.hpp 2014-10-27 19:13:24 +0000
@@ -45,9 +45,10 @@
45 //! Define the drawing mode when drawing polygons45 //! Define the drawing mode when drawing polygons
46 enum SphericalPolygonDrawMode46 enum SphericalPolygonDrawMode
47 {47 {
48 SphericalPolygonDrawModeFill=0, //!< Draw the interior of the polygon48 SphericalPolygonDrawModeFill=0, //!< Draw the interior of the polygon
49 SphericalPolygonDrawModeBoundary=1, //!< Draw the boundary of the polygon49 SphericalPolygonDrawModeBoundary=1, //!< Draw the boundary of the polygon
50 SphericalPolygonDrawModeTextureFill=2 //!< Draw the interior of the polygon filled with the current texture50 SphericalPolygonDrawModeTextureFill=2, //!< Draw the interior of the polygon filled with the current texture
51 SphericalPolygonDrawModeTextureFillColormodulated=3 //!< Draw the interior of the polygon filled with the current texture multiplied by vertex colors
51 };52 };
5253
53 //! Define the drawing mode when drawing vertex54 //! Define the drawing mode when drawing vertex
@@ -97,7 +98,7 @@
9798
98 void drawGreatCircleArcs(const StelVertexArray& va, const SphericalCap* clippingCap=NULL);99 void drawGreatCircleArcs(const StelVertexArray& va, const SphericalCap* clippingCap=NULL);
99100
100 void drawSphericalTriangles(const StelVertexArray& va, const bool textured, const SphericalCap* clippingCap=NULL, const bool doSubDivide=true, const double maxSqDistortion=5.);101 void drawSphericalTriangles(const StelVertexArray& va, const bool textured, const bool colored, const SphericalCap* clippingCap=NULL, const bool doSubDivide=true, const double maxSqDistortion=5.);
101102
102 //! Draw a small circle arc between points start and stop with rotation point in rotCenter.103 //! Draw a small circle arc between points start and stop with rotation point in rotCenter.
103 //! The angle between start and stop must be < 180 deg.104 //! The angle between start and stop must be < 180 deg.
@@ -165,7 +166,7 @@
165 //! @param slices: number of vertical segments ("meridian zones")166 //! @param slices: number of vertical segments ("meridian zones")
166 //! @param stacks: number of horizontal segments ("latitude zones")167 //! @param stacks: number of horizontal segments ("latitude zones")
167 //! @param orientInside: 1 to have normals point inside, e.g. for landscape horizons168 //! @param orientInside: 1 to have normals point inside, e.g. for landscape horizons
168 //! @param flipTexture: if texture should be mapped to inside of shere, e.g. landscape horizons.169 //! @param flipTexture: if texture should be mapped to inside of sphere, e.g. landscape horizons.
169 //! @param topAngle GZ: new parameter. An opening angle [radians] at top of the sphere. Useful if there is an empty170 //! @param topAngle GZ: new parameter. An opening angle [radians] at top of the sphere. Useful if there is an empty
170 //! region around the top pole, like for a spherical equirectangular horizon panorama (@class SphericalLandscape).171 //! region around the top pole, like for a spherical equirectangular horizon panorama (@class SphericalLandscape).
171 //! Example: your horizon line (pano photo) goes up to 26 degrees altitude (highest mountains/trees):172 //! Example: your horizon line (pano photo) goes up to 26 degrees altitude (highest mountains/trees):
@@ -178,8 +179,19 @@
178 const float topAngle=0.0f, const float bottomAngle=M_PI);179 const float topAngle=0.0f, const float bottomAngle=M_PI);
179180
180 //! Generate a StelVertexArray for a sphere.181 //! Generate a StelVertexArray for a sphere.
182 //! @param radius
183 //! @param oneMinusOblateness
184 //! @param slices: number of vertical segments ("meridian zones")
185 //! @param stacks: number of horizontal segments ("latitude zones")
186 //! @param orientInside: 1 to have normals point inside, e.g. for Milky Way, Zodiacal Light, etc.
187 //! @param flipTexture: if texture should be mapped to inside of sphere, e.g. Milky Way.
188 //! @param topAngle GZ: new parameter. An opening angle [radians] at top of the sphere. Useful if there is an empty
189 //! region around the top pole, like North Galactic Pole.
190 //! @param bottomAngle GZ: new parameter. An opening angle [radians] at bottom of the sphere. Useful if there is an empty
191 //! region around the bottom pole, like South Galactic Pole.
181 static StelVertexArray computeSphereNoLight(const float radius, const float oneMinusOblateness, const int slices, const int stacks,192 static StelVertexArray computeSphereNoLight(const float radius, const float oneMinusOblateness, const int slices, const int stacks,
182 const int orientInside = 0, const bool flipTexture = false);193 const int orientInside = 0, const bool flipTexture = false,
194 const float topAngle=0.0f, const float bottomAngle=M_PI);
183195
184 //! Re-implementation of gluCylinder : glu is overridden for non-standard projection.196 //! Re-implementation of gluCylinder : glu is overridden for non-standard projection.
185 void sCylinder(const float radius, const float height, const int slices, const int orientInside = 0);197 void sCylinder(const float radius, const float height, const int slices, const int orientInside = 0);
@@ -304,8 +316,11 @@
304 //! @param vertices a pointer to an array of 3 vertices.316 //! @param vertices a pointer to an array of 3 vertices.
305 //! @param edgeFlags a pointer to an array of 3 flags indicating whether the next segment is an edge.317 //! @param edgeFlags a pointer to an array of 3 flags indicating whether the next segment is an edge.
306 //! @param texturePos a pointer to an array of 3 texture coordinates, or NULL if the triangle should not be textured.318 //! @param texturePos a pointer to an array of 3 texture coordinates, or NULL if the triangle should not be textured.
319 //! @param colors a pointer to an array of 3 colors, or NULL if the triangle should not be vertex-colored. If texture and color coords are present, texture is modulated by vertex colors. (e.g. extinction)
307 void projectSphericalTriangle(const SphericalCap* clippingCap, const Vec3d* vertices, QVarLengthArray<Vec3f, 4096>* outVertices,320 void projectSphericalTriangle(const SphericalCap* clippingCap, const Vec3d* vertices, QVarLengthArray<Vec3f, 4096>* outVertices,
308 const Vec2f* texturePos=NULL, QVarLengthArray<Vec2f, 4096>* outTexturePos=NULL, const double maxSqDistortion=5., const int nbI=0,321 const Vec2f* texturePos=NULL, QVarLengthArray<Vec2f, 4096>* outTexturePos=NULL,
322 const Vec3f* colors=NULL, QVarLengthArray<Vec3f, 4096>* outColors=NULL,
323 const double maxSqDistortion=5., const int nbI=0,
309 const bool checkDisc1=true, const bool checkDisc2=true, const bool checkDisc3=true) const;324 const bool checkDisc1=true, const bool checkDisc2=true, const bool checkDisc3=true) const;
310325
311 void drawTextGravity180(float x, float y, const QString& str, const float xshift = 0, const float yshift = 0);326 void drawTextGravity180(float x, float y, const QString& str, const float xshift = 0, const float yshift = 0);
312327
=== modified file 'src/core/StelProjector.hpp'
--- src/core/StelProjector.hpp 2014-04-18 19:29:32 +0000
+++ src/core/StelProjector.hpp 2014-10-27 19:13:24 +0000
@@ -45,7 +45,7 @@
45 //! Shared pointer on a ModelViewTranform instance (implement reference counting)45 //! Shared pointer on a ModelViewTranform instance (implement reference counting)
46 typedef QSharedPointer<ModelViewTranform> ModelViewTranformP;46 typedef QSharedPointer<ModelViewTranform> ModelViewTranformP;
4747
48 //! @class PreModelViewFunc48 //! @class ModelViewTranform
49 //! Allows to define non linear operations in addition to the standard linear (Matrix 4d) ModelView transformation.49 //! Allows to define non linear operations in addition to the standard linear (Matrix 4d) ModelView transformation.
50 class ModelViewTranform50 class ModelViewTranform
51 {51 {
5252
=== modified file 'src/core/StelSphereGeometry.cpp'
--- src/core/StelSphereGeometry.cpp 2014-04-19 09:40:17 +0000
+++ src/core/StelSphereGeometry.cpp 2014-10-27 19:13:24 +0000
@@ -709,7 +709,8 @@
709709
710 TriangleSerializer() {}710 TriangleSerializer() {}
711 inline void operator()(const Vec3d* v1, const Vec3d* v2, const Vec3d* v3,711 inline void operator()(const Vec3d* v1, const Vec3d* v2, const Vec3d* v3,
712 const Vec2f* , const Vec2f* , const Vec2f* ,712 const Vec2f* , const Vec2f* , const Vec2f* ,
713 const Vec3f* , const Vec3f* , const Vec3f* , // GZ NEW
713 unsigned int , unsigned int , unsigned int )714 unsigned int , unsigned int , unsigned int )
714 {715 {
715 QVariantList triangle;716 QVariantList triangle;
@@ -1151,7 +1152,8 @@
11511152
1152 TriangleDumper() {}1153 TriangleDumper() {}
1153 inline void operator()(const Vec3d* v1, const Vec3d* v2, const Vec3d* v3,1154 inline void operator()(const Vec3d* v1, const Vec3d* v2, const Vec3d* v3,
1154 const Vec2f* , const Vec2f* , const Vec2f* ,1155 const Vec2f* , const Vec2f* , const Vec2f* ,
1156 const Vec3f* , const Vec3f* , const Vec3f* , // GZ NEW
1155 unsigned int , unsigned int , unsigned int )1157 unsigned int , unsigned int , unsigned int )
1156 {1158 {
1157 QVector<Vec3d> triangle;1159 QVector<Vec3d> triangle;
11581160
=== modified file 'src/core/StelSphereGeometry.hpp'
--- src/core/StelSphereGeometry.hpp 2014-02-20 15:07:04 +0000
+++ src/core/StelSphereGeometry.hpp 2014-10-27 19:13:24 +0000
@@ -284,7 +284,7 @@
284 //! @param an a unit vector indicating the direction.284 //! @param an a unit vector indicating the direction.
285 //! @param ar cosinus of the aperture.285 //! @param ar cosinus of the aperture.
286 SphericalCap(const Vec3d& an, double ar) : n(an), d(ar) {//n.normalize();286 SphericalCap(const Vec3d& an, double ar) : n(an), d(ar) {//n.normalize();
287 Q_ASSERT(d==0 || std::fabs(n.lengthSquared()-1.)<0.0000001);}287 Q_ASSERT(d==0 || std::fabs(n.lengthSquared()-1.)<0.0000001);}
288 // FIXME: GZ reports 2013-03-02: apparently the Q_ASSERT is here because n should be normalized at this point, but288 // FIXME: GZ reports 2013-03-02: apparently the Q_ASSERT is here because n should be normalized at this point, but
289 // for efficiency n.normalize() should not be called at this point.289 // for efficiency n.normalize() should not be called at this point.
290 // However, when zooming in a bit in Hammer-Aitoff and Mercator projections, this Assertion fires.290 // However, when zooming in a bit in Hammer-Aitoff and Mercator projections, this Assertion fires.
291291
=== modified file 'src/core/StelUtils.cpp'
--- src/core/StelUtils.cpp 2014-10-26 11:18:06 +0000
+++ src/core/StelUtils.cpp 2014-10-27 19:13:24 +0000
@@ -546,13 +546,11 @@
546 *lng = atan2(v[1],v[0]);546 *lng = atan2(v[1],v[0]);
547}547}
548548
549// GZ: some additions. I need those just for quick conversions for text display.
550void ctRadec2Ecl(const double raRad, const double decRad, const double eclRad, double *lambdaRad, double *betaRad)549void ctRadec2Ecl(const double raRad, const double decRad, const double eclRad, double *lambdaRad, double *betaRad)
551{550{
552 *lambdaRad=std::atan2(std::sin(raRad)*std::cos(eclRad)+std::tan(decRad)*std::sin(eclRad), std::cos(raRad));551 *lambdaRad=std::atan2(std::sin(raRad)*std::cos(eclRad)+std::tan(decRad)*std::sin(eclRad), std::cos(raRad));
553 *betaRad=std::asin(std::sin(decRad)*std::cos(eclRad)-std::cos(decRad)*std::sin(eclRad)*std::sin(raRad));552 *betaRad=std::asin(std::sin(decRad)*std::cos(eclRad)-std::cos(decRad)*std::sin(eclRad)*std::sin(raRad));
554}553}
555// GZ: done
556554
557double getDecAngle(const QString& str)555double getDecAngle(const QString& str)
558{556{
@@ -1265,8 +1263,6 @@
1265 // "Five Millennium Canon of Solar Eclipses" [Espenak and Meeus, 2006]1263 // "Five Millennium Canon of Solar Eclipses" [Espenak and Meeus, 2006]
1266 // A summary is described here:1264 // A summary is described here:
1267 // http://eclipse.gsfc.nasa.gov/SEhelp/deltatpoly2004.html1265 // http://eclipse.gsfc.nasa.gov/SEhelp/deltatpoly2004.html
1268 // GZ: I replaced the std::pow() calls by Horner's scheme with reversed factors, it's more accurate and efficient.
1269 // Old code left for readability, but can also be deleted.
12701266
1271 double y = year+((month-1)*30.5+day/31*30.5)/366;1267 double y = year+((month-1)*30.5+day/31*30.5)/366;
12721268
@@ -1532,7 +1528,7 @@
15321528
1533// Implementation of algorithm by JPL Horizons for DeltaT computation1529// Implementation of algorithm by JPL Horizons for DeltaT computation
1534double getDeltaTByJPLHorizons(const double jDay)1530double getDeltaTByJPLHorizons(const double jDay)
1535{ // GZ: TODO: FIXME! It does not make sense to have zeros after 1620 in a JPL Horizons compatible implementation!1531{ // TODO: FIXME! It does not make sense to have zeros after 1620 in a JPL Horizons compatible implementation!
1536 int year, month, day;1532 int year, month, day;
1537 double u;1533 double u;
1538 double deltaT = 0.;1534 double deltaT = 0.;
@@ -1716,16 +1712,16 @@
1716}1712}
17171713
1718// Implementation of algorithm by Reingold & Dershowitz (Cal. Calc. 1997, 2001, 2007, Cal. Tab. 2002) for DeltaT computation.1714// Implementation of algorithm by Reingold & Dershowitz (Cal. Calc. 1997, 2001, 2007, Cal. Tab. 2002) for DeltaT computation.
1719// GZ: Created as yet another multi-segment polynomial fit through the table in Meeus: Astronomical Algorithms (1991).1715// Created as yet another multi-segment polynomial fit through the table in Meeus: Astronomical Algorithms (1991).
1720// GZ: Note that only the Third edition (2007) adds the 1700-1799 term.1716// Note that only the Third edition (2007) adds the 1700-1799 term.
1721// GZ: More efficient reimplementation with stricter adherence to the source.1717// More efficient reimplementation with stricter adherence to the source.
1722double getDeltaTByReingoldDershowitz(const double jDay)1718double getDeltaTByReingoldDershowitz(const double jDay)
1723{1719{
1724 int year, month, day; 1720 int year, month, day;
1725 getDateFromJulianDay(jDay, &year, &month, &day);1721 getDateFromJulianDay(jDay, &year, &month, &day);
1726 // GZ: R&D don't use a float-fraction year, but explicitly only the integer year! And R&D use a proleptic Gregorian year before 1582.1722 // R&D don't use a float-fraction year, but explicitly only the integer year! And R&D use a proleptic Gregorian year before 1582.
1727 // GZ: We cannot do that, but the difference is negligible.1723 // We cannot do that, but the difference is negligible.
1728 // GZ: FIXME: why are displayed values so far off the computed values? It seems currently broken!1724 // FIXME: why are displayed values so far off the computed values? It seems currently broken!
1729 double deltaT=0.0; // If it returns 0, there is a bug!1725 double deltaT=0.0; // If it returns 0, there is a bug!
17301726
1731 if ((year >= 2019) || (year < 1620))1727 if ((year >= 2019) || (year < 1620))
@@ -1945,7 +1941,7 @@
1945//! Compute cosines and sines around part of a circle (from top to bottom) which is split in "segments" parts.1941//! Compute cosines and sines around part of a circle (from top to bottom) which is split in "segments" parts.
1946//! Values are stored in the global static array cos_sin_rho.1942//! Values are stored in the global static array cos_sin_rho.
1947//! Used for the sin/cos values along a meridian.1943//! Used for the sin/cos values along a meridian.
1948//! GZ: allow leaving away pole caps. The array now contains values for the region minAngle+segments*phi1944//! This allows leaving away pole caps. The array now contains values for the region minAngle+segments*phi
1949//! @param dRho a difference angle between the stops1945//! @param dRho a difference angle between the stops
1950//! @param segments number of segments1946//! @param segments number of segments
1951//! @param minAngle start angle inside the half-circle. maxAngle=minAngle+segments*phi1947//! @param minAngle start angle inside the half-circle. maxAngle=minAngle+segments*phi
19521948
=== modified file 'src/core/StelUtils.hpp'
--- src/core/StelUtils.hpp 2014-10-26 11:18:06 +0000
+++ src/core/StelUtils.hpp 2014-10-27 19:13:24 +0000
@@ -174,10 +174,8 @@
174 //! @param v the input 3D vector174 //! @param v the input 3D vector
175 void rectToSphe(float *lng, float *lat, const Vec3f& v);175 void rectToSphe(float *lng, float *lat, const Vec3f& v);
176176
177 // GZ: some additions. I need those just for quick conversions for text display.
178 //! Coordinate Transformation from equatorial to ecliptical177 //! Coordinate Transformation from equatorial to ecliptical
179 void ctRadec2Ecl(const double raRad, const double decRad, const double eclRad, double *lambdaRad, double *betaRad);178 void ctRadec2Ecl(const double raRad, const double decRad, const double eclRad, double *lambdaRad, double *betaRad);
180 // GZ: done
181179
182 //! Convert a string longitude, latitude, RA or Declination angle180 //! Convert a string longitude, latitude, RA or Declination angle
183 //! to radians.181 //! to radians.
@@ -611,7 +609,7 @@
611 //! Compute cosines and sines around part of a circle (from top to bottom) which is split in "segments" parts.609 //! Compute cosines and sines around part of a circle (from top to bottom) which is split in "segments" parts.
612 //! Values are stored in the global static array cos_sin_rho.610 //! Values are stored in the global static array cos_sin_rho.
613 //! Used for the sin/cos values along a meridian.611 //! Used for the sin/cos values along a meridian.
614 //! GZ: allow leaving away pole caps. The array now contains values for the region minAngle+segments*phi612 //! This allows leaving away pole caps. The array now contains values for the region minAngle+segments*phi
615 //! @param dRho a difference angle between the stops613 //! @param dRho a difference angle between the stops
616 //! @param segments number of segments614 //! @param segments number of segments
617 //! @param minAngle start angle inside the half-circle. maxAngle=minAngle+segments*phi615 //! @param minAngle start angle inside the half-circle. maxAngle=minAngle+segments*phi
618616
=== modified file 'src/core/StelVertexArray.cpp'
--- src/core/StelVertexArray.cpp 2014-04-06 12:19:27 +0000
+++ src/core/StelVertexArray.cpp 2014-10-27 19:13:24 +0000
@@ -100,7 +100,7 @@
100 Q_ASSERT(false);100 Q_ASSERT(false);
101 }101 }
102 }102 }
103 // Just in case we don't have any triangles, we also remove all the vertex.103 // Just in case we don't have any triangles, we also remove all the vertices.
104 // This is because we can't specify an empty indexed VertexArray.104 // This is because we can't specify an empty indexed VertexArray.
105 // FIXME: we should use an attribute for indexed array.105 // FIXME: we should use an attribute for indexed array.
106 if (ret.indices.isEmpty())106 if (ret.indices.isEmpty())
@@ -114,6 +114,7 @@
114{114{
115 out << p.vertex;115 out << p.vertex;
116 out << p.texCoords;116 out << p.texCoords;
117 out << p.colors; // GZ NEW
117 out << p.indices;118 out << p.indices;
118 out << (unsigned int)p.primitiveType;119 out << (unsigned int)p.primitiveType;
119 return out;120 return out;
@@ -123,6 +124,7 @@
123{124{
124 in >> p.vertex;125 in >> p.vertex;
125 in >> p.texCoords;126 in >> p.texCoords;
127 in >> p.colors; // GZ NEW
126 in >> p.indices;128 in >> p.indices;
127 unsigned int t;129 unsigned int t;
128 in >> t;130 in >> t;
129131
=== modified file 'src/core/StelVertexArray.hpp'
--- src/core/StelVertexArray.hpp 2014-02-18 06:36:58 +0000
+++ src/core/StelVertexArray.hpp 2014-10-27 19:13:24 +0000
@@ -49,6 +49,9 @@
49 QVector<Vec3d> vertex;49 QVector<Vec3d> vertex;
50 //! OpenGL compatible array of edge flags to be displayed using vertex arrays.50 //! OpenGL compatible array of edge flags to be displayed using vertex arrays.
51 QVector<Vec2f> texCoords;51 QVector<Vec2f> texCoords;
52 //! OpenGL compatible array of vertex colors to be displayed using arrays. (GZ/NEW)
53 //! The color (if exists) shall be multiplied with texture to modulate e.g. for extinction of Milky Way or other large items.
54 QVector<Vec3f> colors;
52 //! OpenGL compatible array of indices for the vertex and the textures55 //! OpenGL compatible array of indices for the vertex and the textures
53 QVector<unsigned short> indices;56 QVector<unsigned short> indices;
5457
@@ -58,20 +61,24 @@
5861
59 bool isTextured() const {return !texCoords.isEmpty();}62 bool isTextured() const {return !texCoords.isEmpty();}
6063
64 bool isColored() const {return !colors.isEmpty();}
65
66
61 //! call a function for each triangle of the array.67 //! call a function for each triangle of the array.
62 //! func should define the following method :68 //! func should define the following method : // GZ NEW: colors
63 //! void operator() (const Vec3d* vertex[3], const Vec2f* tex[3], unsigned int indices[3])69 //! void operator() (const Vec3d* vertex[3], const Vec2f* tex[3], const Vec3f* colors[3], unsigned int indices[3])
64 //! The method takes arrays of *pointers* as arguments because we can't assume the values are contiguous70 //! The method takes arrays of *pointers* as arguments because we can't assume the values are contiguous
65 template<class Func>71 template<class Func>
66 inline Func foreachTriangle(Func func) const;72 inline Func foreachTriangle(Func func) const;
6773
68 //! Create a copy of the array with all the triangles intersecting the projector discontinuty removed.74 //! Create a copy of the array with all the triangles intersecting the projector discontinuity removed.
69 StelVertexArray removeDiscontinuousTriangles(const class StelProjector* prj) const;75 StelVertexArray removeDiscontinuousTriangles(const class StelProjector* prj) const;
7076
71private:77private:
72 // Below we define a few methods that are templated to be optimized according to different types of VertexArray :78 // Below we define a few methods that are templated to be optimized according to different types of VertexArray :
73 // The template parameter <bool T> defines whether the array has a texture.79 // The template parameter <bool T> defines whether the array has a texture.
74 // The template parameter <bool I> defines whether the array is indexed.80 // The template parameter <bool I> defines whether the array is indexed.
81 // The template parameter <bool C> defines whether the array is colored. // NEW GZ
75 template <bool I>82 template <bool I>
76 const Vec3d* specVertexAt(int i) const {83 const Vec3d* specVertexAt(int i) const {
77 return &vertex.at(specIndiceAt<I>(i));84 return &vertex.at(specIndiceAt<I>(i));
@@ -82,12 +89,18 @@
82 return T ? &texCoords.at(specIndiceAt<I>(i)) : NULL;89 return T ? &texCoords.at(specIndiceAt<I>(i)) : NULL;
83 }90 }
8491
92 // NEW GZ
93 template <bool C, bool I>
94 const Vec3f* specColorAt(int i) const {
95 return C ? &colors.at(specIndiceAt<I>(i)) : NULL;
96 }
97
85 template<bool I>98 template<bool I>
86 unsigned int specIndiceAt(unsigned int i) const {99 unsigned int specIndiceAt(unsigned int i) const {
87 return I ? indices.at(i) : i;100 return I ? indices.at(i) : i;
88 }101 }
89102
90 template<bool T, bool I, class Func>103 template<bool T, bool I, bool C, class Func> // GZ added bool C
91 inline Func specForeachTriangle(Func func) const;104 inline Func specForeachTriangle(Func func) const;
92105
93};106};
@@ -99,23 +112,49 @@
99template<class Func>112template<class Func>
100Func StelVertexArray::foreachTriangle(Func func) const113Func StelVertexArray::foreachTriangle(Func func) const
101{114{
102 // Here we just dispach the method into one of the 4 possible cases115 // Here we just dispatch the method into one of the 8 possible cases // GZ NEW: 8, not 4, cases
103 bool textured = isTextured();116 bool textured = isTextured();
117 bool colored = isColored();
104 bool useIndice = isIndexed();118 bool useIndice = isIndexed();
105119
106 if (textured)120 if (textured)
107 if (useIndice)121 {
108 return specForeachTriangle<true, true, Func>(func);122 if (useIndice)
109 else123 {
110 return specForeachTriangle<true, false, Func>(func);124 if (colored)
111 else125 return specForeachTriangle<true, true, true, Func>(func);
112 if (useIndice)126 else
113 return specForeachTriangle<false, true, Func>(func);127 return specForeachTriangle<true, true, false, Func>(func);
114 else128 }
115 return specForeachTriangle<false, false, Func>(func);129 else // not indiced
130 {
131 if (colored)
132 return specForeachTriangle<true, false, true, Func>(func);
133 else
134 return specForeachTriangle<true, false, false, Func>(func);
135 }
136 }
137 else // not textured
138 {
139 if (useIndice)
140 {
141 if (colored)
142 return specForeachTriangle<false, true, true, Func>(func);
143 else
144 return specForeachTriangle<false, true, false, Func>(func);
145 }
146 else // not indiced
147 {
148 if (colored)
149 return specForeachTriangle<false, false, true, Func>(func);
150 else
151 return specForeachTriangle<false, false, false, Func>(func);
152 }
153 }
154 Q_ASSERT(0); // GZ. Just make sure...
116}155}
117156
118template<bool T, bool I, class Func>157template<bool T, bool I, bool C, class Func>
119Func StelVertexArray::specForeachTriangle(Func func) const158Func StelVertexArray::specForeachTriangle(Func func) const
120{159{
121 switch (primitiveType)160 switch (primitiveType)
@@ -126,6 +165,7 @@
126 {165 {
127 func(specVertexAt<I>(i), specVertexAt<I>(i+1), specVertexAt<I>(i+2),166 func(specVertexAt<I>(i), specVertexAt<I>(i+1), specVertexAt<I>(i+2),
128 specTexCoordAt<T, I>(i), specTexCoordAt<T, I>(i+1), specTexCoordAt<T, I>(i+2),167 specTexCoordAt<T, I>(i), specTexCoordAt<T, I>(i+1), specTexCoordAt<T, I>(i+2),
168 specColorAt<C, I>(i), specColorAt<C, I>(i+1), specColorAt<C, I>(i+2),
129 specIndiceAt<I>(i), specIndiceAt<I>(i+1), specIndiceAt<I>(i+2));169 specIndiceAt<I>(i), specIndiceAt<I>(i+1), specIndiceAt<I>(i+2));
130 }170 }
131 break;171 break;
@@ -133,12 +173,14 @@
133 {173 {
134 const Vec3d* v0 = specVertexAt<I>(0);174 const Vec3d* v0 = specVertexAt<I>(0);
135 const Vec2f* t0 = specTexCoordAt<T, I>(0);175 const Vec2f* t0 = specTexCoordAt<T, I>(0);
176 const Vec3f* c0 = specColorAt<C, I>(0);
136 unsigned int i0 = specIndiceAt<I>(0);177 unsigned int i0 = specIndiceAt<I>(0);
137 for (int i = 1; i < vertex.size() - 1; ++i)178 for (int i = 1; i < vertex.size() - 1; ++i)
138 {179 {
139 func(v0, specVertexAt<I>(i), specVertexAt<I>(i+1),180 func(v0, specVertexAt<I>(i), specVertexAt<I>(i+1),
140 t0, specTexCoordAt<T, I>(i), specTexCoordAt<T, I>(i+1),181 t0, specTexCoordAt<T, I>(i), specTexCoordAt<T, I>(i+1),
141 i0, specIndiceAt<I>(i), specIndiceAt<I>(i+1));182 c0, specColorAt<C, I>(i), specColorAt<C, I>(i+1),
183 i0, specIndiceAt<I>(i), specIndiceAt<I>(i+1));
142 }184 }
143 break;185 break;
144 }186 }
@@ -149,16 +191,18 @@
149 if (i % 2 == 0)191 if (i % 2 == 0)
150 func(specVertexAt<I>(i-2), specVertexAt<I>(i-1), specVertexAt<I>(i),192 func(specVertexAt<I>(i-2), specVertexAt<I>(i-1), specVertexAt<I>(i),
151 specTexCoordAt<T, I>(i-2), specTexCoordAt<T, I>(i-1), specTexCoordAt<T, I>(i),193 specTexCoordAt<T, I>(i-2), specTexCoordAt<T, I>(i-1), specTexCoordAt<T, I>(i),
194 specColorAt<C, I>(i-2), specColorAt<C, I>(i-1), specColorAt<C, I>(i),
152 specIndiceAt<I>(i-2), specIndiceAt<I>(i-1), specIndiceAt<I>(i));195 specIndiceAt<I>(i-2), specIndiceAt<I>(i-1), specIndiceAt<I>(i));
153 else196 else
154 func(specVertexAt<I>(i-1), specVertexAt<I>(i-2), specVertexAt<I>(i),197 func(specVertexAt<I>(i-1), specVertexAt<I>(i-2), specVertexAt<I>(i),
155 specTexCoordAt<T, I>(i-1), specTexCoordAt<T, I>(i-2), specTexCoordAt<T, I>(i),198 specTexCoordAt<T, I>(i-1), specTexCoordAt<T, I>(i-2), specTexCoordAt<T, I>(i),
199 specColorAt<C, I>(i-1), specColorAt<C, I>(i-2), specColorAt<C, I>(i),
156 specIndiceAt<I>(i-1), specIndiceAt<I>(i-2), specIndiceAt<I>(i));200 specIndiceAt<I>(i-1), specIndiceAt<I>(i-2), specIndiceAt<I>(i));
157 }201 }
158 break;202 break;
159 }203 }
160 default:204 default:
161 Q_ASSERT_X(0, Q_FUNC_INFO, "unsuported primitive type");205 Q_ASSERT_X(0, Q_FUNC_INFO, "unsupported primitive type");
162 }206 }
163 return func;207 return func;
164}208}
165209
=== modified file 'src/core/modules/Landscape.cpp'
--- src/core/modules/Landscape.cpp 2014-10-25 00:04:08 +0000
+++ src/core/modules/Landscape.cpp 2014-10-27 19:13:24 +0000
@@ -589,7 +589,7 @@
589 if (side.light==drawLight)589 if (side.light==drawLight)
590 {590 {
591 side.tex->bind();591 side.tex->bind();
592 sPainter.drawSphericalTriangles(side.arr, true, NULL, false);592 sPainter.drawSphericalTriangles(side.arr, true, false, NULL, false);
593 }593 }
594 }594 }
595}595}
596596
=== modified file 'src/core/modules/MilkyWay.cpp'
--- src/core/modules/MilkyWay.cpp 2014-04-15 17:10:07 +0000
+++ src/core/modules/MilkyWay.cpp 2014-10-27 19:13:24 +0000
@@ -1,6 +1,7 @@
1/*1/*
2 * Stellarium2 * Stellarium
3 * Copyright (C) 2002 Fabien Chereau3 * Copyright (C) 2002 Fabien Chereau
4 * Copyright (C) 2014 Georg Zotti (extinction parts)
4 *5 *
5 * This program is free software; you can redistribute it and/or6 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License7 * modify it under the terms of the GNU General Public License
@@ -58,15 +59,35 @@
58 QSettings* conf = StelApp::getInstance().getSettings();59 QSettings* conf = StelApp::getInstance().getSettings();
59 Q_ASSERT(conf);60 Q_ASSERT(conf);
6061
61 tex = StelApp::getInstance().getTextureManager().createTexture(StelFileMgr::getInstallationDir()+"/textures/milkyway.png");62 //tex = StelApp::getInstance().getTextureManager().createTexture(StelFileMgr::getInstallationDir()+"/textures/milkyway.png");
63 tex = StelApp::getInstance().getTextureManager().createTexture(StelFileMgr::getInstallationDir()+"/textures/milkyway_2048.png");
62 setFlagShow(conf->value("astro/flag_milky_way").toBool());64 setFlagShow(conf->value("astro/flag_milky_way").toBool());
63 setIntensity(conf->value("astro/milky_way_intensity",1.f).toFloat());65 setIntensity(conf->value("astro/milky_way_intensity",1.f).toFloat());
6466 // GZ: I cut the original milkyway.png 512x512 to 512x256. Center line was shifted southwards by 32 pixels to keep Magellanic Clouds visible.
65 vertexArray = new StelVertexArray(StelPainter::computeSphereNoLight(1.f,1.f,20,20,1));67 // 256px were 90 degrees. 128:45, 64:22.5, 32:11.25. So this spherical ring goes from -45-11.25 to 45-11.25.
66}68
6769 // A new texture was provided by Fabien. Better resolution, but in equatorial coordinates. I had to enhance it a bit, and shift it by 90 degrees.
6870 // GZ: Note that a full sphere (i.e., a texture not aligned to galactic coordinates) costs performance!
69void MilkyWay::update(double deltaTime) {fader->update((int)(deltaTime*1000));}71 //vertexArray = new StelVertexArray(StelPainter::computeSphereNoLight(1.f,1.f,45,15,1, true, (90.0f-33.75f)*M_PI/180.0f, (90.0f+56.25f)*M_PI/180.0f)); // GZ orig: slices=stacks=20.
72 vertexArray = new StelVertexArray(StelPainter::computeSphereNoLight(1.f,1.f,45,15,1, true)); // GZ orig: slices=stacks=20.
73 vertexArray->colors.resize(vertexArray->vertex.length());
74 vertexArray->colors.fill(Vec3f(1.0, 0.3, 0.9));
75
76 // If we have a texture in galactic coordinates, we can transform the vertex coordinates already here.
77 // The texture had to be rotated/flipped and shifted compared to 0.13.0
78// StelCore* core=StelApp::getInstance().getCore();
79// for (int i=0; i<vertexArray->vertex.size(); ++i)
80// {
81// Vec3d tmp=vertexArray->vertex.at(i);
82// vertexArray->vertex.replace(i, core->galacticToJ2000(tmp));
83// }
84}
85
86
87void MilkyWay::update(double deltaTime)
88{
89 fader->update((int)(deltaTime*1000));
90}
7091
71void MilkyWay::setFlagShow(bool b){*fader = b;}92void MilkyWay::setFlagShow(bool b){*fader = b;}
72bool MilkyWay::getFlagShow() const {return *fader;}93bool MilkyWay::getFlagShow() const {return *fader;}
@@ -77,27 +98,36 @@
77 return;98 return;
7899
79 StelProjector::ModelViewTranformP transfo = core->getJ2000ModelViewTransform();100 StelProjector::ModelViewTranformP transfo = core->getJ2000ModelViewTransform();
80 transfo->combine(Mat4d::xrotation(M_PI/180.*23.)*101 // GZ: No idea where this came from. Empirical correction? Now the vertices have been replaced already in init().
81 Mat4d::yrotation(M_PI/180.*120.)*102 // (the "official" angles are not integers...)
82 Mat4d::zrotation(M_PI/180.*7.));103// transfo->combine(Mat4d::xrotation(M_PI/180.*23.)*
104// Mat4d::yrotation(M_PI/180.*120.)*
105// Mat4d::zrotation(M_PI/180.*7.));
83106
84 const StelProjectorP prj = core->getProjection(transfo);107 const StelProjectorP prj = core->getProjection(transfo); // GZ: Maybe this can now be simplified?
85 StelToneReproducer* eye = core->getToneReproducer();108 StelToneReproducer* eye = core->getToneReproducer();
86109
87 Q_ASSERT(tex); // A texture must be loaded before calling this110 Q_ASSERT(tex); // A texture must be loaded before calling this
88111
89 // This RGB color corresponds to the night blue scotopic color = 0.25, 0.25 in xyY mode.112 // This RGB color corresponds to the night blue scotopic color = 0.25, 0.25 in xyY mode.
90 // since milky way is always seen white RGB value in the texture (1.0,1.0,1.0)113 // since milky way is always seen white RGB value in the texture (1.0,1.0,1.0)
91 Vec3f c = Vec3f(0.34165f, 0.429666f, 0.63586f);114 // Vec3f c = Vec3f(0.34165f, 0.429666f, 0.63586f);
115 // GZ: This is the same color, just brighter to have Blue=1.
116 Vec3f c = Vec3f(0.53730381f, .675724216f, 1.0f);
92117
93 float lum = core->getSkyDrawer()->surfacebrightnessToLuminance(13.5f);118 float lum = core->getSkyDrawer()->surfacebrightnessToLuminance(13.5f); // Source? How to calibrate the new texture?
94119
95 // Get the luminance scaled between 0 and 1120 // Get the luminance scaled between 0 and 1
96 float aLum =eye->adaptLuminanceScaled(lum*fader->getInterstate());121 float aLum =eye->adaptLuminanceScaled(lum*fader->getInterstate());
97122
98 // Bound a maximum luminance123 // Bound a maximum luminance. GZ: Is there any reference/reason, or just trial and error?
99 aLum = qMin(0.38f, aLum*2.f);124 aLum = qMin(0.38f, aLum*2.f);
100125
126 // GZ I have the impression we must also adjust milky way to light pollution.
127 // Is there any way to calibrate this?
128 int bortle=core->getSkyDrawer()->getBortleScaleIndex();
129 aLum*=(11.0f-bortle)*0.1f;
130
101 // intensity of 1.0 is "proper", but allow boost for dim screens131 // intensity of 1.0 is "proper", but allow boost for dim screens
102 c*=aLum*intensity;132 c*=aLum*intensity;
103133
@@ -105,8 +135,31 @@
105 if (c[1]<0) c[1]=0;135 if (c[1]<0) c[1]=0;
106 if (c[2]<0) c[2]=0;136 if (c[2]<0) c[2]=0;
107137
138 const bool withExtinction=(core->getSkyDrawer()->getFlagHasAtmosphere() && core->getSkyDrawer()->getExtinction().getExtinctionCoefficient()>=0.01f);
139
140 if (withExtinction)
141 {
142 // We must process the vertices to find geometric altitudes in order to compute vertex colors.
143 // Note that there is a visible boost of extinction for higher Bortle indices. I must reflect that as well.
144 Extinction extinction=core->getSkyDrawer()->getExtinction();
145 vertexArray->colors.clear();
146
147 for (int i=0; i<vertexArray->vertex.size(); ++i)
148 {
149 Vec3d vertAltAz=core->j2000ToAltAz(vertexArray->vertex.at(i), StelCore::RefractionOn);
150 Q_ASSERT(vertAltAz.lengthSquared()-1.0 < 0.001f);
151
152 float oneMag=0.0f;
153 extinction.forward(vertAltAz, &oneMag);
154 float extinctionFactor=std::pow(0.4f , oneMag) * (1.0f-bortle*0.1f); // drop of one magnitude: factor 2.5 or 40%
155 Vec3f thisColor=Vec3f(c[0]*extinctionFactor, c[1]*extinctionFactor, c[2]*extinctionFactor);
156 vertexArray->colors.append(thisColor);
157 }
158 }
159 else
160 vertexArray->colors.fill(Vec3f(c[0], c[1], c[2]));
161
108 StelPainter sPainter(prj);162 StelPainter sPainter(prj);
109 sPainter.setColor(c[0],c[1],c[2]);
110 glEnable(GL_CULL_FACE);163 glEnable(GL_CULL_FACE);
111 sPainter.enableTexture2d(true);164 sPainter.enableTexture2d(true);
112 glDisable(GL_BLEND);165 glDisable(GL_BLEND);
113166
=== modified file 'src/core/modules/MilkyWay.hpp'
--- src/core/modules/MilkyWay.hpp 2014-04-15 17:10:07 +0000
+++ src/core/modules/MilkyWay.hpp 2014-10-27 19:13:24 +0000
@@ -71,7 +71,7 @@
71 71
72private:72private:
73 StelTextureSP tex;73 StelTextureSP tex;
74 Vec3f color;74 Vec3f color; // global color
75 float intensity;75 float intensity;
76 class LinearFader* fader;76 class LinearFader* fader;
7777
7878
=== modified file 'src/core/modules/Nebula.hpp'
--- src/core/modules/Nebula.hpp 2014-04-06 14:34:01 +0000
+++ src/core/modules/Nebula.hpp 2014-10-27 19:13:24 +0000
@@ -30,6 +30,7 @@
30class StelPainter;30class StelPainter;
31class QDataStream;31class QDataStream;
3232
33// This only draws nebula icons. For the DSO images, see StelSkylayerMgr and StelSkyImageTile.
33class Nebula : public StelObject34class Nebula : public StelObject
34{35{
35friend class NebulaMgr;36friend class NebulaMgr;
3637
=== modified file 'src/gui/LocationDialog.hpp'
--- src/gui/LocationDialog.hpp 2014-09-08 12:47:22 +0000
+++ src/gui/LocationDialog.hpp 2014-10-27 19:13:24 +0000
@@ -82,7 +82,7 @@
82 void updateFromProgram(const StelLocation& location);82 void updateFromProgram(const StelLocation& location);
83 83
84 //! Called when the map is clicked.84 //! Called when the map is clicked.
85 //! GZ_New: create new list for places nearby and feed into location list box.85 //! create new list for places nearby and feed into location list box.
86 void setPositionFromMap(double longitude, double latitude);86 void setPositionFromMap(double longitude, double latitude);
87 87
88 //! Called when the user activates an item from the locations list.88 //! Called when the user activates an item from the locations list.
8989
=== modified file 'textures/milkyway.png'
90Binary files textures/milkyway.png 2005-10-30 19:51:28 +0000 and textures/milkyway.png 2014-10-27 19:13:24 +0000 differ90Binary files textures/milkyway.png 2005-10-30 19:51:28 +0000 and textures/milkyway.png 2014-10-27 19:13:24 +0000 differ
=== added file 'textures/milkyway_2048.png'
91Binary files textures/milkyway_2048.png 1970-01-01 00:00:00 +0000 and textures/milkyway_2048.png 2014-10-27 19:13:24 +0000 differ91Binary files textures/milkyway_2048.png 1970-01-01 00:00:00 +0000 and textures/milkyway_2048.png 2014-10-27 19:13:24 +0000 differ