1 ////////////////////////////////////////////////////////////////////////////////
2 // Scorched3D (c) 2000-2009
4 // This file is part of Scorched3D.
6 // Scorched3D is free software; you can redistribute it and/or modify
7 // it under the terms of the GNU General Public License as published by
8 // the Free Software Foundation; either version 2 of the License, or
9 // (at your option) any later version.
11 // Scorched3D is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // You should have received a copy of the GNU General Public License
17 // along with Scorched3D; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 ////////////////////////////////////////////////////////////////////////////////
21 #include <sky/SkyRoof.h>
24 #include <landscape/Landscape.h>
25 #include <landscapedef/LandscapeDefinition.h>
26 #include <landscapedef/LandscapeTex.h>
27 #include <landscapedef/LandscapeDefn.h>
28 #include <landscapemap/LandscapeMaps.h>
29 #include <client/ScorchedClient.h>
30 #include <engine/ScorchedContext.h>
31 #include <GLEXT/GLInfo.h>
32 #include <common/Defines.h>
35 SkyRoof::SkyRoof() : list_(0), tris_(0)
43 void SkyRoof::generate()
45 if (list_
) glDeleteLists(list_
, 1);
50 void SkyRoof::makeNormal(Vector
&position
, Vector
&normal
)
53 *ScorchedClient::instance()->getLandscapeMaps().getDefinitions().getTex();
54 Vector
&ambient
= tex
.skyambience
;
55 Vector
&diffuse
= tex
.skydiffuse
;
56 Vector
&sunPos
= Landscape::instance()->getSky().getSun().getPosition();
57 Vector sunDirection
= (sunPos
- position
).Normalize();
59 float diffuseLight
= (((normal
.dotP(sunDirection
)) / 2.0f
) + 0.5f
);
60 Vector light
= diffuse
* diffuseLight
+ ambient
;
61 light
[0] = MIN(1.0f
, light
[0]);
62 light
[1] = MIN(1.0f
, light
[1]);
63 light
[2] = MIN(1.0f
, light
[2]);
68 void SkyRoof::makeList()
70 HeightMap
&rmap
= ScorchedClient::instance()->
71 getLandscapeMaps().getRoofMaps().getRoofMap();
72 HeightMap
&hmap
= ScorchedClient::instance()->
73 getLandscapeMaps().getGroundMaps().getHeightMap();
75 float multWidth
= float(hmap
.getMapWidth()) / float(rmap
.getMapWidth());
76 float multHeight
= float(hmap
.getMapHeight()) / float(rmap
.getMapHeight());
78 glNewList(list_
= glGenLists(1), GL_COMPILE
);
79 for (int j
=0; j
<rmap
.getMapHeight(); j
++)
81 glBegin(GL_QUAD_STRIP
);
82 for (int i
=0; i
<=rmap
.getMapWidth(); i
++)
84 Vector
a(i
* multWidth
, j
* multHeight
, rmap
.getHeight(i
, j
).asFloat());
85 makeNormal(a
, rmap
.getNormal(i
, j
).asVector());
86 glTexCoord2f(a
[0] / float(rmap
.getMapWidth()), a
[1] / float(rmap
.getMapHeight()));
89 Vector
b(i
* multWidth
, (j
+ 1) * multHeight
, rmap
.getHeight(i
, j
+ 1).asFloat());
90 makeNormal(b
, rmap
.getNormal(i
, j
+ 1).asVector());
91 glTexCoord2f(b
[0] / float(rmap
.getMapWidth()), b
[1] / float(rmap
.getMapHeight()));
99 for (int i
=0; i
<rmap
.getMapWidth(); i
++)
102 Vector
a(i
* multWidth
, 0.0f
, rmap
.getHeight(i
, 0).asFloat());
103 Vector na
= rmap
.getNormal(i
,0).asVector();
104 Vector
b((i
+ 1) * multWidth
, 0.0f
, rmap
.getHeight(i
+ 1, 0).asFloat());
105 Vector nb
= rmap
.getNormal(i
+ 1, 0).asVector();
106 drawSegment(a
, b
, na
, nb
);
109 Vector
b(i
* multWidth
, (float) hmap
.getMapHeight(),
110 rmap
.getHeight(i
, rmap
.getMapHeight()).asFloat());
111 Vector nb
= rmap
.getNormal(i
, rmap
.getMapHeight()).asVector();
112 Vector
a((i
+ 1) * multWidth
, (float) hmap
.getMapHeight(),
113 rmap
.getHeight(i
+ 1, rmap
.getMapHeight()).asFloat());
114 Vector na
= rmap
.getNormal(i
+ 1, rmap
.getMapHeight()).asVector();
115 drawSegment(a
, b
, na
, nb
);
118 for (int i
=0; i
<rmap
.getMapHeight(); i
++)
121 Vector
b(0.0f
, i
* multHeight
, rmap
.getHeight(0, i
).asFloat());
122 Vector nb
= rmap
.getNormal(0, i
).asVector();
123 Vector
a(0.0f
, (i
+ 1) * multHeight
, rmap
.getHeight(0, i
+ 1).asFloat());
124 Vector na
= rmap
.getNormal(0, i
+ 1).asVector();
125 drawSegment(a
, b
, na
, nb
);
128 Vector
a((float) hmap
.getMapWidth(), i
* multHeight
,
129 rmap
.getHeight(rmap
.getMapWidth(), i
).asFloat());
130 Vector na
= rmap
.getNormal(rmap
.getMapWidth(), i
).asVector();
131 Vector
b((float) hmap
.getMapWidth(), (i
+ 1) * multHeight
,
132 rmap
.getHeight(rmap
.getMapWidth(), i
+ 1).asFloat());
133 Vector nb
= rmap
.getNormal(rmap
.getMapWidth(), i
+ 1).asVector();
134 drawSegment(a
, b
, na
, nb
);
141 void SkyRoof::drawSegment(Vector
&a
, Vector
&b
, Vector
&na
, Vector
&nb
)
143 HeightMap
&rmap
= ScorchedClient::instance()->
144 getLandscapeMaps().getRoofMaps().getRoofMap();
145 HeightMap
&hmap
= ScorchedClient::instance()->
146 getLandscapeMaps().getGroundMaps().getHeightMap();
147 LandscapeDefn
&defn
=
148 *ScorchedClient::instance()->getLandscapeMaps().getDefinitions().getDefn();
149 LandscapeDefnRoofCavern
*cavern
=
150 (LandscapeDefnRoofCavern
*) defn
.roof
;
151 float hemispehereRadius
= cavern
->width
.asFloat();
155 float heighta
= a
[2];
156 float heightb
= b
[2];
157 Vector
midPointA(float(hmap
.getMapWidth() / 2), float(hmap
.getMapHeight() / 2), heighta
);
158 Vector
midPointB(float(hmap
.getMapWidth() / 2), float(hmap
.getMapHeight() / 2), heightb
);
160 Vector diffa
= (a
- midPointA
);
161 Vector diffb
= (b
- midPointB
);
162 float dista
= diffa
.Magnitude();
163 float distb
= diffb
.Magnitude();
164 diffa
.StoreNormalize();
165 diffb
.StoreNormalize();
166 diffa
*= (hemispehereRadius
- dista
) / float(steps
);
167 diffb
*= (hemispehereRadius
- distb
) / float(steps
);
169 glBegin(GL_QUAD_STRIP
);
170 for (int i
=0; i
<=steps
+ 3; i
++)
173 Vector c
= a
+ diffa
;
174 Vector e
= (a
- c
).Normalize();
175 Vector f
= (a
- b
).Normalize();
178 glTexCoord2f(a
[0] / float(hmap
.getMapWidth()), a
[1] / float(hmap
.getMapHeight()));
185 Vector c
= b
+ diffb
;
186 Vector f
= (b
- c
).Normalize();
187 Vector e
= (b
- a
).Normalize();
190 glTexCoord2f(b
[0] / float(hmap
.getMapWidth()), b
[1] / float(hmap
.getMapHeight()));
198 a
[2] = heighta
* cosf(1.57f
* float(i
) / float(steps
));
199 b
[2] = heightb
* cosf(1.57f
* float(i
) / float(steps
));
208 if (!list_
) makeList();
210 GLInfo::addNoTriangles(tris_
);
211 Landscape::instance()->getRoofTexture().draw(true);