1
1
/*
2
2
Minetest
3
3
Copyright (C) 2010-2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4
+ Copyright (C) 2020 numzero, Lobachevskiy Vitaliy <numzer0@yandex.ru>
4
5
5
6
This program is free software; you can redistribute it and/or modify
6
7
it under the terms of the GNU Lesser General Public License as published by
@@ -34,16 +35,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
34
35
#include " config.h"
35
36
using namespace irr ::core;
36
37
37
- Sky::Sky (s32 id, ITextureSource *tsrc) :
38
- scene::ISceneNode(RenderingEngine::get_scene_manager()->getRootSceneNode(),
39
- RenderingEngine::get_scene_manager(), id)
40
- {
41
- setAutomaticCulling (scene::EAC_OFF);
42
- m_box.MaxEdge .set (0 , 0 , 0 );
43
- m_box.MinEdge .set (0 , 0 , 0 );
44
-
45
- // Create material
46
-
38
+ static video::SMaterial baseMaterial () {
47
39
video::SMaterial mat;
48
40
mat.Lighting = false ;
49
41
#if ENABLE_GLES
@@ -56,14 +48,29 @@ Sky::Sky(s32 id, ITextureSource *tsrc) :
56
48
mat.TextureLayer [0 ].TextureWrapU = video::ETC_CLAMP_TO_EDGE;
57
49
mat.TextureLayer [0 ].TextureWrapV = video::ETC_CLAMP_TO_EDGE;
58
50
mat.BackfaceCulling = false ;
51
+ return mat;
52
+ };
53
+
54
+ Sky::Sky (s32 id, ITextureSource *tsrc) :
55
+ scene::ISceneNode(RenderingEngine::get_scene_manager()->getRootSceneNode(),
56
+ RenderingEngine::get_scene_manager(), id)
57
+ {
58
+ setAutomaticCulling (scene::EAC_OFF);
59
+ m_box.MaxEdge .set (0 , 0 , 0 );
60
+ m_box.MinEdge .set (0 , 0 , 0 );
61
+
62
+ // Create materials
59
63
60
- m_materials[0 ] = mat;
64
+ m_materials[0 ] = baseMaterial ();
65
+ m_materials[0 ].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
66
+ m_materials[0 ].Lighting = true ;
67
+ m_materials[0 ].ColorMaterial = video::ECM_NONE;
61
68
62
- m_materials[1 ] = mat ;
69
+ m_materials[1 ] = baseMaterial () ;
63
70
// m_materials[1].MaterialType = video::EMT_TRANSPARENT_VERTEX_ALPHA;
64
71
m_materials[1 ].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
65
72
66
- m_materials[2 ] = mat ;
73
+ m_materials[2 ] = baseMaterial () ;
67
74
m_materials[2 ].setTexture (0 , tsrc->getTextureForMesh (" sunrisebg.png" ));
68
75
m_materials[2 ].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
69
76
// m_materials[2].MaterialType = video::EMT_TRANSPARENT_ADD_COLOR;
@@ -80,7 +87,7 @@ Sky::Sky(s32 id, ITextureSource *tsrc) :
80
87
tsrc->getTexture (m_moon_params.tonemap ) : NULL ;
81
88
82
89
if (m_sun_texture) {
83
- m_materials[3 ] = mat ;
90
+ m_materials[3 ] = baseMaterial () ;
84
91
m_materials[3 ].setTexture (0 , m_sun_texture);
85
92
m_materials[3 ].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
86
93
// Disables texture filtering
@@ -92,7 +99,7 @@ Sky::Sky(s32 id, ITextureSource *tsrc) :
92
99
m_materials[3 ].Lighting = true ;
93
100
}
94
101
if (m_moon_texture) {
95
- m_materials[4 ] = mat ;
102
+ m_materials[4 ] = baseMaterial () ;
96
103
m_materials[4 ].setTexture (0 , m_moon_texture);
97
104
m_materials[4 ].MaterialType = video::EMT_TRANSPARENT_ALPHA_CHANNEL;
98
105
// Disables texture filtering
@@ -105,7 +112,7 @@ Sky::Sky(s32 id, ITextureSource *tsrc) :
105
112
}
106
113
107
114
for (int i = 5 ; i < 11 ; i++) {
108
- m_materials[i] = mat ;
115
+ m_materials[i] = baseMaterial () ;
109
116
m_materials[i].Lighting = true ;
110
117
m_materials[i].MaterialType = video::EMT_SOLID;
111
118
}
@@ -673,101 +680,32 @@ void Sky::draw_moon(video::IVideoDriver *driver, float moonsize, const video::SC
673
680
c = video::SColor (255 , 255 , 255 , 255 );
674
681
draw_sky_body (vertices, -d, d, c);
675
682
place_sky_body (vertices, -90 , wicked_time_of_day * 360 - 90 );
676
- driver->drawIndexedTriangleFan (&vertices[0 ], 4 , indices, 2 );
683
+ driver->drawIndexedTriangleList (&vertices[0 ], 4 , indices, 2 );
677
684
}
678
685
}
679
686
680
687
void Sky::draw_stars (video::IVideoDriver * driver, float wicked_time_of_day)
681
688
{
682
- driver->setMaterial (m_materials[1 ]);
683
689
// Tune values so that stars first appear just after the sun
684
690
// disappears over the horizon, and disappear just before the sun
685
691
// appears over the horizon.
686
692
// Also tune so that stars are at full brightness from time 20000
687
693
// to time 4000.
688
694
689
695
float tod = wicked_time_of_day < 0 .5f ? wicked_time_of_day : (1 .0f - wicked_time_of_day);
690
- float starbrightness = clamp ((0 .25f - fabsf (tod)) * 20 .0f , 0 .0f , 1 .0f );
691
-
692
- float f = starbrightness;
693
- float d = (0.006 / 2 ) * m_star_params.scale ;
694
-
695
- video::SColor starcolor = m_star_params.starcolor ;
696
- starcolor.setAlpha (f * m_star_params.starcolor .getAlpha ());
697
-
698
- // Stars are only drawn when not fully transparent
699
- if (m_star_params.starcolor .getAlpha () < 1 )
696
+ float starbrightness = (0 .25f - fabsf (tod)) * 20 .0f ;
697
+ int alpha = clamp<int >(starbrightness * m_star_params.starcolor .getAlpha (), 0 , 255 );
698
+ if (!alpha) // Stars are only drawn when not fully transparent
700
699
return ;
701
- #if ENABLE_GLES
702
- u16 *indices = new u16[m_star_params.count * 3 ];
703
- video::S3DVertex *vertices =
704
- new video::S3DVertex[m_star_params.count * 3 ];
705
- for (u32 i = 0 ; i < m_star_params.count ; i++) {
706
- indices[i * 3 + 0 ] = i * 3 + 0 ;
707
- indices[i * 3 + 1 ] = i * 3 + 1 ;
708
- indices[i * 3 + 2 ] = i * 3 + 2 ;
709
- v3f r = m_stars[i];
710
- core::CMatrix4<f32> a;
711
- a.buildRotateFromTo (v3f (0 , 1 , 0 ), r);
712
- v3f p = v3f (-d, 1 , -d);
713
- v3f p1 = v3f (d, 1 , 0 );
714
- v3f p2 = v3f (-d, 1 , d);
715
- a.rotateVect (p);
716
- a.rotateVect (p1);
717
- a.rotateVect (p2);
718
- p.rotateXYBy (wicked_time_of_day * 360 - 90 );
719
- p1.rotateXYBy (wicked_time_of_day * 360 - 90 );
720
- p2.rotateXYBy (wicked_time_of_day * 360 - 90 );
721
- vertices[i * 3 + 0 ].Pos = p;
722
- vertices[i * 3 + 0 ].Color = starcolor;
723
- vertices[i * 3 + 1 ].Pos = p1;
724
- vertices[i * 3 + 1 ].Color = starcolor;
725
- vertices[i * 3 + 2 ].Pos = p2;
726
- vertices[i * 3 + 2 ].Color = starcolor;
727
- }
728
- driver->drawIndexedTriangleList (vertices, m_star_params.count * 3 ,
729
- indices, m_star_params.count );
730
- delete[] indices;
731
- delete[] vertices;
732
- #else
733
- u16 *indices = new u16[m_star_params.count * 4 ];
734
- video::S3DVertex *vertices =
735
- new video::S3DVertex[m_star_params.count * 4 ];
736
- for (u32 i = 0 ; i < m_star_params.count ; i++) {
737
- indices[i * 4 + 0 ] = i * 4 + 0 ;
738
- indices[i * 4 + 1 ] = i * 4 + 1 ;
739
- indices[i * 4 + 2 ] = i * 4 + 2 ;
740
- indices[i * 4 + 3 ] = i * 4 + 3 ;
741
- v3f r = m_stars[i];
742
- core::CMatrix4<f32> a;
743
- a.buildRotateFromTo (v3f (0 , 1 , 0 ), r);
744
- v3f p = v3f (-d, 1 , -d);
745
- v3f p1 = v3f (d, 1 , -d);
746
- v3f p2 = v3f (d, 1 , d);
747
- v3f p3 = v3f (-d, 1 , d);
748
- a.rotateVect (p);
749
- a.rotateVect (p1);
750
- a.rotateVect (p2);
751
- a.rotateVect (p3);
752
- p.rotateXYBy (wicked_time_of_day * 360 - 90 );
753
- p1.rotateXYBy (wicked_time_of_day * 360 - 90 );
754
- p2.rotateXYBy (wicked_time_of_day * 360 - 90 );
755
- p3.rotateXYBy (wicked_time_of_day * 360 - 90 );
756
- vertices[i * 4 + 0 ].Pos = p;
757
- vertices[i * 4 + 0 ].Color = starcolor;
758
- vertices[i * 4 + 1 ].Pos = p1;
759
- vertices[i * 4 + 1 ].Color = starcolor;
760
- vertices[i * 4 + 2 ].Pos = p2;
761
- vertices[i * 4 + 2 ].Color = starcolor;
762
- vertices[i * 4 + 3 ].Pos = p3;
763
- vertices[i * 4 + 3 ].Color = starcolor;
764
- }
765
- driver->drawVertexPrimitiveList (vertices, m_star_params.count * 4 ,
766
- indices, m_star_params.count , video::EVT_STANDARD,
767
- scene::EPT_QUADS, video::EIT_16BIT);
768
- delete[] indices;
769
- delete[] vertices;
770
- #endif
700
+
701
+ m_materials[0 ].DiffuseColor = video::SColor (alpha, 0 , 0 , 0 );
702
+ m_materials[0 ].EmissiveColor = m_star_params.starcolor ;
703
+ auto sky_rotation = core::matrix4 ().setRotationAxisRadians (2 .0f * M_PI * (wicked_time_of_day - 0 .25f ), v3f (0 .0f , 0 .0f , 1 .0f ));
704
+ auto world_matrix = driver->getTransform (video::ETS_WORLD);
705
+ driver->setTransform (video::ETS_WORLD, world_matrix * sky_rotation);
706
+ driver->setMaterial (m_materials[0 ]);
707
+ driver->drawMeshBuffer (m_stars.get ());
708
+ driver->setTransform (video::ETS_WORLD, world_matrix);
771
709
}
772
710
773
711
void Sky::draw_sky_body (std::array<video::S3DVertex, 4 > &vertices, float pos_1, float pos_2, const video::SColor &c)
@@ -822,7 +760,7 @@ void Sky::setSunTexture(std::string sun_texture,
822
760
m_sun_texture = tsrc->getTextureForMesh (m_sun_params.texture );
823
761
824
762
if (m_sun_texture) {
825
- m_materials[3 ] = m_materials[ 0 ] ;
763
+ m_materials[3 ] = baseMaterial () ;
826
764
m_materials[3 ].setTexture (0 , m_sun_texture);
827
765
m_materials[3 ].MaterialType = video::
828
766
EMT_TRANSPARENT_ALPHA_CHANNEL;
@@ -870,7 +808,7 @@ void Sky::setMoonTexture(std::string moon_texture,
870
808
m_moon_texture = tsrc->getTextureForMesh (m_moon_params.texture );
871
809
872
810
if (m_moon_texture) {
873
- m_materials[4 ] = m_materials[ 0 ] ;
811
+ m_materials[4 ] = baseMaterial () ;
874
812
m_materials[4 ].setTexture (0 , m_moon_texture);
875
813
m_materials[4 ].MaterialType = video::
876
814
EMT_TRANSPARENT_ALPHA_CHANNEL;
@@ -892,19 +830,54 @@ void Sky::setStarCount(u16 star_count, bool force_update)
892
830
// Allow force updating star count at game init.
893
831
if (m_star_params.count != star_count || force_update) {
894
832
m_star_params.count = star_count;
895
- m_stars.clear ();
896
- // Rebuild the stars surrounding the camera
897
- for (u16 i = 0 ; i < star_count; i++) {
898
- v3f star = v3f (
899
- myrand_range (-10000 , 10000 ),
900
- myrand_range (-10000 , 10000 ),
901
- myrand_range (-10000 , 10000 )
902
- );
903
-
904
- star.normalize ();
905
- m_stars.emplace_back (star);
906
- }
833
+ updateStars ();
834
+ }
835
+ }
836
+
837
+ void Sky::updateStars () {
838
+ m_stars.reset (new scene::SMeshBuffer ());
839
+ // Stupid IrrLicht doesn’t allow non-indexed rendering, and indexed quad
840
+ // rendering is slow due to lack of hardware support. So as indices are
841
+ // 16-bit and there are 4 vertices per star... the limit is 2^16/4 = 0x4000.
842
+ // That should be well enough actually.
843
+ if (m_star_params.count > 0x4000 ) {
844
+ warningstream << " Requested " << m_star_params.count << " stars but " << 0x4000 << " is the max\n " ;
845
+ m_star_params.count = 0x4000 ;
846
+ }
847
+ m_stars->Vertices .reallocate (4 * m_star_params.count );
848
+ m_stars->Indices .reallocate (6 * m_star_params.count );
849
+
850
+ float d = (0.006 / 2 ) * m_star_params.scale ;
851
+ for (u16 i = 0 ; i < m_star_params.count ; i++) {
852
+ v3f r = v3f (
853
+ myrand_range (-10000 , 10000 ),
854
+ myrand_range (-10000 , 10000 ),
855
+ myrand_range (-10000 , 10000 )
856
+ );
857
+ core::CMatrix4<f32> a;
858
+ a.buildRotateFromTo (v3f (0 , 1 , 0 ), r);
859
+ v3f p = v3f (-d, 1 , -d);
860
+ v3f p1 = v3f (d, 1 , -d);
861
+ v3f p2 = v3f (d, 1 , d);
862
+ v3f p3 = v3f (-d, 1 , d);
863
+ a.rotateVect (p);
864
+ a.rotateVect (p1);
865
+ a.rotateVect (p2);
866
+ a.rotateVect (p3);
867
+ m_stars->Vertices .push_back (video::S3DVertex (p, {}, {}, {}));
868
+ m_stars->Vertices .push_back (video::S3DVertex (p1, {}, {}, {}));
869
+ m_stars->Vertices .push_back (video::S3DVertex (p2, {}, {}, {}));
870
+ m_stars->Vertices .push_back (video::S3DVertex (p3, {}, {}, {}));
871
+ }
872
+ for (u16 i = 0 ; i < m_star_params.count ; i++) {
873
+ m_stars->Indices .push_back (i * 4 + 0 );
874
+ m_stars->Indices .push_back (i * 4 + 1 );
875
+ m_stars->Indices .push_back (i * 4 + 2 );
876
+ m_stars->Indices .push_back (i * 4 + 2 );
877
+ m_stars->Indices .push_back (i * 4 + 3 );
878
+ m_stars->Indices .push_back (i * 4 + 0 );
907
879
}
880
+ m_stars->setHardwareMappingHint (scene::EHM_STATIC);
908
881
}
909
882
910
883
void Sky::setSkyColors (const SkyColor &sky_color)
@@ -936,7 +909,7 @@ void Sky::addTextureToSkybox(std::string texture, int material_id,
936
909
// Keep a list of texture names handy.
937
910
m_sky_params.textures .emplace_back (texture);
938
911
video::ITexture *result = tsrc->getTextureForMesh (texture);
939
- m_materials[material_id+5 ] = m_materials[ 0 ] ;
912
+ m_materials[material_id+5 ] = baseMaterial () ;
940
913
m_materials[material_id+5 ].setTexture (0 , result);
941
914
m_materials[material_id+5 ].MaterialType = video::EMT_SOLID;
942
915
}
0 commit comments