00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <sky/SkyRoof.h>
00022 #include <sky/Sky.h>
00023 #include <sky/Sun.h>
00024 #include <landscape/Landscape.h>
00025 #include <landscapedef/LandscapeDefinition.h>
00026 #include <landscapedef/LandscapeTex.h>
00027 #include <landscapedef/LandscapeDefn.h>
00028 #include <landscapemap/LandscapeMaps.h>
00029 #include <client/ScorchedClient.h>
00030 #include <engine/ScorchedContext.h>
00031 #include <GLEXT/GLInfo.h>
00032 #include <common/Defines.h>
00033 #include <math.h>
00034
00035 SkyRoof::SkyRoof() : list_(0), tris_(0)
00036 {
00037 }
00038
00039 SkyRoof::~SkyRoof()
00040 {
00041 }
00042
00043 void SkyRoof::generate()
00044 {
00045 if (list_) glDeleteLists(list_, 1);
00046 list_ = 0;
00047 tris_ = 0;
00048 }
00049
00050 void SkyRoof::makeNormal(Vector &position, Vector &normal)
00051 {
00052 LandscapeTex &tex =
00053 *ScorchedClient::instance()->getLandscapeMaps().getDefinitions().getTex();
00054 Vector &ambient = tex.skyambience;
00055 Vector &diffuse = tex.skydiffuse;
00056 Vector &sunPos = Landscape::instance()->getSky().getSun().getPosition();
00057 Vector sunDirection = (sunPos - position).Normalize();
00058
00059 float diffuseLight = (((normal.dotP(sunDirection)) / 2.0f) + 0.5f);
00060 Vector light = diffuse * diffuseLight + ambient;
00061 light[0] = MIN(1.0f, light[0]);
00062 light[1] = MIN(1.0f, light[1]);
00063 light[2] = MIN(1.0f, light[2]);
00064
00065 glColor3fv(light);
00066 }
00067
00068 void SkyRoof::makeList()
00069 {
00070 HeightMap &rmap = ScorchedClient::instance()->
00071 getLandscapeMaps().getRoofMaps().getRoofMap();
00072 HeightMap &hmap = ScorchedClient::instance()->
00073 getLandscapeMaps().getGroundMaps().getHeightMap();
00074
00075 float multWidth = float(hmap.getMapWidth()) / float(rmap.getMapWidth());
00076 float multHeight = float(hmap.getMapHeight()) / float(rmap.getMapHeight());
00077
00078 glNewList(list_ = glGenLists(1), GL_COMPILE);
00079 for (int j=0; j<rmap.getMapHeight(); j++)
00080 {
00081 glBegin(GL_QUAD_STRIP);
00082 for (int i=0; i<=rmap.getMapWidth(); i++)
00083 {
00084 Vector a(i * multWidth, j * multHeight, rmap.getHeight(i, j).asFloat());
00085 makeNormal(a, rmap.getNormal(i, j).asVector());
00086 glTexCoord2f(a[0] / float(rmap.getMapWidth()), a[1] / float(rmap.getMapHeight()));
00087 glVertex3fv(a);
00088
00089 Vector b(i * multWidth, (j + 1) * multHeight, rmap.getHeight(i, j + 1).asFloat());
00090 makeNormal(b, rmap.getNormal(i, j + 1).asVector());
00091 glTexCoord2f(b[0] / float(rmap.getMapWidth()), b[1] / float(rmap.getMapHeight()));
00092 glVertex3fv(b);
00093
00094 tris_ += 2;
00095 }
00096 glEnd();
00097 }
00098
00099 for (int i=0; i<rmap.getMapWidth(); i++)
00100 {
00101 {
00102 Vector a(i * multWidth, 0.0f, rmap.getHeight(i, 0).asFloat());
00103 Vector na = rmap.getNormal(i,0).asVector();
00104 Vector b((i + 1) * multWidth, 0.0f, rmap.getHeight(i + 1, 0).asFloat());
00105 Vector nb = rmap.getNormal(i + 1, 0).asVector();
00106 drawSegment(a, b, na, nb);
00107 }
00108 {
00109 Vector b(i * multWidth, (float) hmap.getMapHeight(),
00110 rmap.getHeight(i, rmap.getMapHeight()).asFloat());
00111 Vector nb = rmap.getNormal(i, rmap.getMapHeight()).asVector();
00112 Vector a((i + 1) * multWidth, (float) hmap.getMapHeight(),
00113 rmap.getHeight(i + 1, rmap.getMapHeight()).asFloat());
00114 Vector na = rmap.getNormal(i + 1, rmap.getMapHeight()).asVector();
00115 drawSegment(a, b, na, nb);
00116 }
00117 }
00118 for (int i=0; i<rmap.getMapHeight(); i++)
00119 {
00120 {
00121 Vector b(0.0f, i * multHeight, rmap.getHeight(0, i).asFloat());
00122 Vector nb = rmap.getNormal(0, i).asVector();
00123 Vector a(0.0f, (i + 1) * multHeight, rmap.getHeight(0, i + 1).asFloat());
00124 Vector na = rmap.getNormal(0, i + 1).asVector();
00125 drawSegment(a, b, na, nb);
00126 }
00127 {
00128 Vector a((float) hmap.getMapWidth(), i * multHeight,
00129 rmap.getHeight(rmap.getMapWidth(), i).asFloat());
00130 Vector na = rmap.getNormal(rmap.getMapWidth(), i).asVector();
00131 Vector b((float) hmap.getMapWidth(), (i + 1) * multHeight,
00132 rmap.getHeight(rmap.getMapWidth(), i + 1).asFloat());
00133 Vector nb = rmap.getNormal(rmap.getMapWidth(), i + 1).asVector();
00134 drawSegment(a, b, na, nb);
00135 }
00136 }
00137
00138 glEndList();
00139 }
00140
00141 void SkyRoof::drawSegment(Vector &a, Vector &b, Vector &na, Vector &nb)
00142 {
00143 HeightMap &rmap = ScorchedClient::instance()->
00144 getLandscapeMaps().getRoofMaps().getRoofMap();
00145 HeightMap &hmap = ScorchedClient::instance()->
00146 getLandscapeMaps().getGroundMaps().getHeightMap();
00147 LandscapeDefn &defn =
00148 *ScorchedClient::instance()->getLandscapeMaps().getDefinitions().getDefn();
00149 LandscapeDefnRoofCavern *cavern =
00150 (LandscapeDefnRoofCavern *) defn.roof;
00151 float hemispehereRadius = cavern->width.asFloat();
00152
00153 const int steps = 5;
00154
00155 float heighta = a[2];
00156 float heightb = b[2];
00157 Vector midPointA(float(hmap.getMapWidth() / 2), float(hmap.getMapHeight() / 2), heighta);
00158 Vector midPointB(float(hmap.getMapWidth() / 2), float(hmap.getMapHeight() / 2), heightb);
00159
00160 Vector diffa = (a - midPointA);
00161 Vector diffb = (b - midPointB);
00162 float dista = diffa.Magnitude();
00163 float distb = diffb.Magnitude();
00164 diffa.StoreNormalize();
00165 diffb.StoreNormalize();
00166 diffa *= (hemispehereRadius - dista) / float(steps);
00167 diffb *= (hemispehereRadius - distb) / float(steps);
00168
00169 glBegin(GL_QUAD_STRIP);
00170 for (int i=0; i<=steps + 3; i++)
00171 {
00172 {
00173 Vector c = a + diffa;
00174 Vector e = (a - c).Normalize();
00175 Vector f = (a - b).Normalize();
00176 Vector n = e * f;
00177
00178 glTexCoord2f(a[0] / float(hmap.getMapWidth()), a[1] / float(hmap.getMapHeight()));
00179 if (i < 1) n = na;
00180 makeNormal(a, n);
00181 glVertex3fv(a);
00182 }
00183
00184 {
00185 Vector c = b + diffb;
00186 Vector f = (b - c).Normalize();
00187 Vector e = (b - a).Normalize();
00188 Vector n = e * f;
00189
00190 glTexCoord2f(b[0] / float(hmap.getMapWidth()), b[1] / float(hmap.getMapHeight()));
00191 if (i < 1) n = nb;
00192 makeNormal(b, n);
00193 glVertex3fv(b);
00194 }
00195
00196 a += diffa;
00197 b += diffb;
00198 a[2] = heighta * cosf(1.57f * float(i) / float(steps));
00199 b[2] = heightb * cosf(1.57f * float(i) / float(steps));
00200
00201 tris_ += 2;
00202 }
00203 glEnd();
00204 }
00205
00206 void SkyRoof::draw()
00207 {
00208 if (!list_) makeList();
00209
00210 GLInfo::addNoTriangles(tris_);
00211 Landscape::instance()->getRoofTexture().draw(true);
00212 glCallList(list_);
00213 }