00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <water/Water.h>
00022 #include <water/Water2.h>
00023 #include <water/Water2Renderer.h>
00024 #include <water/WaterMapPoints.h>
00025 #include <water/WaterWaveDistance.h>
00026 #include <water/WaterWaves.h>
00027 #include <landscapemap/LandscapeMaps.h>
00028 #include <landscapedef/LandscapeTex.h>
00029 #include <landscapedef/LandscapeDefn.h>
00030 #include <landscapedef/LandscapeDefinition.h>
00031 #include <graph/OptionsDisplay.h>
00032 #include <common/Defines.h>
00033 #include <common/Clock.h>
00034 #include <common/Logger.h>
00035 #include <sound/SoundUtils.h>
00036 #include <client/ScorchedClient.h>
00037 #include <graph/ParticleEmitter.h>
00038 #include <image/ImageFactory.h>
00039 #include <GLEXT/GLImageModifier.h>
00040
00041 Water::Water() :
00042 height_(25.0f), waterOn_(false)
00043 {
00044 wTex_ = new Water2Renderer();
00045 wMap_ = new Water2();
00046 wMapPoints_ = new WaterMapPoints();
00047 wWaveDistance_ = new WaterWaveDistance();
00048 waves_ = new WaterWaves();
00049 }
00050
00051 Water::~Water()
00052 {
00053 }
00054
00055 void Water::draw()
00056 {
00057 if (!waterOn_ ||
00058 !OptionsDisplay::instance()->getDrawWater()) return;
00059
00060 wTex_->draw(*wMap_, *wMapPoints_, *waves_);
00061 }
00062
00063 void Water::simulate(float frameTime)
00064 {
00065 if (!waterOn_ ||
00066 !OptionsDisplay::instance()->getDrawWater()) return;
00067
00068 wTex_->simulate(frameTime);
00069 waves_->simulate(frameTime);
00070 }
00071
00072 void Water::generate(ProgressCounter *counter)
00073 {
00074 LandscapeTex &tex = *ScorchedClient::instance()->getLandscapeMaps().
00075 getDefinitions().getTex();
00076 LandscapeDefn &defn = *ScorchedClient::instance()->getLandscapeMaps().
00077 getDefinitions().getDefn();
00078 if (tex.border->getType() == LandscapeTexType::eNone)
00079 {
00080 height_ = 0.0f;
00081 waterOn_ = false;
00082 return;
00083 }
00084
00085
00086 if (tex.border->getType() != LandscapeTexType::eWater)
00087 {
00088 S3D::dialogExit("Landscape", S3D::formatStringBuffer(
00089 "Failed to find border type %i",
00090 tex.border->getType()));
00091 }
00092
00093 LandscapeTexBorderWater *water =
00094 (LandscapeTexBorderWater *) tex.border;
00095
00096
00097 height_ = water->height.asFloat();
00098 waterOn_ = true;
00099
00100
00101 Clock timer;
00102 wMap_->generate(water, counter);
00103 float timeDifference = timer.getTimeDifference();
00104 Logger::log(S3D::formatStringBuffer("Water time %.3f", timeDifference));
00105
00106 wTex_->generate(water, counter);
00107 wMapPoints_->generate();
00108 wWaveDistance_->generate(defn.getLandscapeWidth(), defn.getLandscapeHeight(), height_, counter);
00109
00110
00111 std::string sprayMaskFile = S3D::getDataFile("data/textures/smoke01.bmp");
00112 ImageHandle sprayMaskBitmap =
00113 ImageFactory::loadImageHandle(
00114 sprayMaskFile.c_str(), sprayMaskFile.c_str(), false);
00115 ImageHandle loadedBitmapWater =
00116 ImageFactory::loadImageHandle(S3D::getDataFile(water->reflection.c_str()));
00117 bitmapWater_ = ImageFactory::loadImageHandle(S3D::getDataFile(water->reflection.c_str()));
00118
00119 {
00120 ImageHandle bitmapWater = loadedBitmapWater.createResize(
00121 sprayMaskBitmap.getWidth(), sprayMaskBitmap.getHeight());
00122 ImageHandle textureWaterNew = ImageFactory::createBlank(
00123 sprayMaskBitmap.getWidth(), sprayMaskBitmap.getHeight(), true);
00124 ImageModifier::makeBitmapTransparent(textureWaterNew,
00125 bitmapWater, sprayMaskBitmap);
00126 landTexWater_.replace(textureWaterNew);
00127 }
00128
00129 waves_->generateWaves(height_, counter);
00130 }
00131
00132 void Water::bindWaterReflection()
00133 {
00134 wTex_->bindWaterReflection();
00135 }
00136
00137 void Water::unBindWaterReflection()
00138 {
00139 wTex_->unBindWaterReflection();
00140 }
00141
00142 void Water::drawPoints()
00143 {
00144 wTex_->drawPoints(*wMapPoints_);
00145 }
00146
00147 GLTexture &Water::getReflectionTexture()
00148 {
00149 return wTex_->getReflectionTexture();
00150 }
00151
00152 bool Water::explosion(Vector position, float size)
00153 {
00154 if (!waterOn_ ||
00155 !OptionsDisplay::instance()->getDrawWater()) return false;
00156
00157 if (position[2] < height_)
00158 {
00159 CACHE_SOUND(sound, S3D::getDataFile("data/wav/misc/splash.wav"));
00160 SoundUtils::playAbsoluteSound(VirtualSoundPriority::eAction,
00161 sound, position);
00162
00163 ParticleEmitter sprayemitter;
00164 sprayemitter.setAttributes(
00165 3.0f, 4.0f,
00166 0.5f, 1.0f,
00167 0.01f, 0.02f,
00168 Vector(0.0f, 0.0f, 0.0f), Vector(0.0f, 0.0f, 0.0f),
00169 Vector(0.9f, 0.9f, 0.9f), 0.5f,
00170 Vector(1.0f, 1.0f, 1.0f), 0.7f,
00171 Vector(0.9f, 0.9f, 0.9f), 0.0f,
00172 Vector(1.0f, 1.0f, 1.0f), 0.1f,
00173 3.0f, 3.0f, 4.0f, 4.0f,
00174 3.0f, 3.0f, 4.0f, 4.0f,
00175 Vector(0.0f, 0.0f, -800.0f),
00176 false,
00177 true);
00178 sprayemitter.emitSpray(position,
00179 ScorchedClient::instance()->getParticleEngine(),
00180 size - 2.0f,
00181 &landTexWater_);
00182 return true;
00183 }
00184
00185 return false;
00186 }
00187
00188 float Water::getWaveDistance(int x, int y)
00189 {
00190 return wWaveDistance_->getWaveDistance(x, y);
00191 }
00192
00193 float *Water::getIndexErrors()
00194 {
00195 return wMap_->getIndexErrors();
00196 }