00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <water/Water2Renderer.h>
00022 #include <water/Water2.h>
00023 #include <water/WaterMapPoints.h>
00024 #include <water/WaterWaves.h>
00025 #include <common/Vector4.h>
00026 #include <image/ImageFactory.h>
00027 #include <image/ImageFactory.h>
00028 #include <GLEXT/GLStateExtension.h>
00029 #include <GLEXT/GLCamera.h>
00030 #include <GLEXT/GLTextureCubeMap.h>
00031 #include <client/ScorchedClient.h>
00032 #include <sky/Sky.h>
00033 #include <land/VisibilityPatchGrid.h>
00034 #include <landscapemap/LandscapeMaps.h>
00035 #include <landscapedef/LandscapeTex.h>
00036 #include <landscapedef/LandscapeDefn.h>
00037 #include <landscape/Landscape.h>
00038 #include <graph/MainCamera.h>
00039 #include <graph/OptionsDisplay.h>
00040
00041 #include <water/Water2Constants.h>
00042
00043 Water2Renderer::Water2Renderer() :
00044 waterShader_(0),
00045 currentPatch_(0), totalTime_(0.0f),
00046 noShaderWaterTexture_(0)
00047 {
00048 }
00049
00050 Water2Renderer::~Water2Renderer()
00051 {
00052 }
00053
00054 void Water2Renderer::simulate(float frameTime)
00055 {
00056 totalTime_ += frameTime * 24.0f;
00057 }
00058
00059 void Water2Renderer::draw(Water2 &water2, WaterMapPoints &points, WaterWaves &waves)
00060 {
00061 GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "WATER_PATCHSETUP");
00062
00063 Water2Patches ¤tPatch = water2.getPatch(totalTime_);
00064 if (¤tPatch != currentPatch_)
00065 {
00066 currentPatch_ = ¤tPatch;
00067
00068
00069 if (GLStateExtension::hasShaders() &&
00070 !OptionsDisplay::instance()->getNoWaterMovement() &&
00071 !OptionsDisplay::instance()->getSimpleWaterShaders())
00072 {
00073 normalTexture_.replace(currentPatch_->getNormalMap(),
00074 GLStateExtension::hasHardwareMipmaps());
00075 }
00076 }
00077 GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "WATER_PATCHSETUP");
00078
00079
00080 GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "WATER_WAVES");
00081 waves.draw(*currentPatch_);
00082 GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "WATER_WAVES");
00083
00084
00085 if (GLStateExtension::hasShaders() &&
00086 OptionsDisplay::instance()->getUseWaterTexture())
00087 {
00088 drawWaterShaders(water2);
00089 }
00090 else
00091 {
00092 drawWaterNoShaders(water2);
00093 }
00094
00095 GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "WATER_DRAWPOINTS");
00096 drawPoints(points);
00097 GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "WATER_DRAWPOINTS");
00098 }
00099
00100 void Water2Renderer::drawPoints(WaterMapPoints &points)
00101 {
00102 if (!currentPatch_) return;
00103
00104
00105 points.draw(*currentPatch_);
00106 }
00107
00108 void Water2Renderer::drawWaterShaders(Water2 &water2)
00109 {
00110 GLState state(GLState::LIGHTING_OFF | GLState::TEXTURE_ON | GLState::BLEND_ON);
00111
00112 glPushAttrib(GL_ALL_ATTRIB_BITS);
00113
00114 Vector cameraPos = GLCamera::getCurrentCamera()->getCurrentPos();
00115 cameraPos[2] = -waterHeight_;
00116 waterShader_->use();
00117 waterShader_->set_uniform("viewpos", cameraPos);
00118
00119
00120 if (!OptionsDisplay::instance()->getSimpleWaterShaders())
00121 {
00122 waterShader_->set_gl_texture(currentPatch_->getAOF(), "tex_foamamount", 3);
00123 }
00124
00125
00126 if (Landscape::instance()->getShadowFrameBuffer().bufferValid())
00127 {
00128 glActiveTextureARB(GL_TEXTURE2_ARB);
00129 glEnable(GL_TEXTURE_2D);
00130 waterShader_->set_gl_texture(Landscape::instance()->getShadowFrameBuffer(),
00131 "tex_shadow", 2);
00132 glMatrixMode(GL_TEXTURE);
00133 glLoadMatrixf(Landscape::instance()->getShadowTextureMatrix());
00134 glMatrixMode(GL_MODELVIEW);
00135 }
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148 Vector D_0 = windDir1_ * (windSpeed1_ / (-64.0f * 6.0f));
00149 Vector D_1 = windDir2_ * (windSpeed2_ / (-16.0f * 6.0f));
00150
00151 float mytime = totalTime_ / 24.0f;
00152 Vector noise_0_pos = D_0 * mytime;
00153 Vector noise_1_pos = D_1 * mytime;
00154 noise_0_pos[2] = wavetile_length_rcp * 8.0f;
00155 noise_1_pos[2] = wavetile_length_rcp * 32.0f;
00156
00157
00158
00159
00160
00161 glActiveTextureARB(GL_TEXTURE0);
00162 if (!OptionsDisplay::instance()->getSimpleWaterShaders())
00163 {
00164 waterShader_->set_uniform("noise_xform_0", noise_0_pos);
00165 waterShader_->set_uniform("noise_xform_1", noise_1_pos);
00166 waterShader_->set_gl_texture(normalTexture_, "tex_normal", 0);
00167 }
00168
00169 const float noisetilescale = 1.0f/32.0f;
00170 glMatrixMode(GL_TEXTURE);
00171 glLoadIdentity();
00172 glScalef(noisetilescale, noisetilescale, 1.0f);
00173 glMatrixMode(GL_MODELVIEW);
00174
00175
00176 glActiveTextureARB(GL_TEXTURE1);
00177 glEnable(GL_TEXTURE_2D);
00178 waterShader_->set_gl_texture(reflectionTexture_, "tex_reflection", 1);
00179
00180
00181 glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
00182 drawWater(water2, waterShader_);
00183
00184
00185 waterShader_->use_fixed();
00186
00187 glActiveTextureARB(GL_TEXTURE2);
00188 glMatrixMode(GL_TEXTURE);
00189 glLoadIdentity();
00190 glMatrixMode(GL_MODELVIEW);
00191 glDisable(GL_TEXTURE_2D);
00192
00193 glActiveTextureARB(GL_TEXTURE1);
00194 glMatrixMode(GL_TEXTURE);
00195 glLoadIdentity();
00196 glMatrixMode(GL_MODELVIEW);
00197 glDisable(GL_TEXTURE_2D);
00198
00199 glActiveTextureARB(GL_TEXTURE0);
00200 glMatrixMode(GL_TEXTURE);
00201 glLoadIdentity();
00202 glMatrixMode(GL_MODELVIEW);
00203
00204 glPopAttrib();
00205 }
00206
00207 void Water2Renderer::drawWaterNoShaders(Water2 &water2)
00208 {
00209 glPushAttrib(GL_TEXTURE_BIT);
00210
00211
00212 static float PlaneS[] = { 0.0f, 1.0f / 20.0f, 0.0f, 0.0f };
00213 static float PlaneT[] = { 1.0f / 20.0f, 0.0f, 0.0f, 0.0f };
00214
00215 if (GLStateExtension::hasMultiTex() &&
00216 OptionsDisplay::instance()->getUseWaterTexture())
00217 {
00218
00219 glActiveTextureARB(GL_TEXTURE1);
00220 glEnable(GL_TEXTURE_2D);
00221 glEnable(GL_TEXTURE_GEN_S);
00222 glEnable(GL_TEXTURE_GEN_T);
00223 glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
00224 glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
00225 glTexGenfv(GL_S, GL_OBJECT_PLANE, PlaneS);
00226 glTexGenfv(GL_T, GL_OBJECT_PLANE, PlaneT);
00227 reflectionTexture_.draw(true);
00228
00229 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
00230 glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2);
00231
00232 glActiveTextureARB(GL_TEXTURE0);
00233
00234
00235 glColor4f(0.3f, 0.3f, 0.3f, 0.8f);
00236 }
00237 else
00238 {
00239 glColor4f(0.7f, 0.7f, 0.7f, 0.8f);
00240 }
00241
00242
00243 unsigned int state = 0;
00244 if (!OptionsDisplay::instance()->getNoModelLighting())
00245 {
00246 state =
00247 GLState::LIGHTING_ON |
00248 GLState::LIGHT1_ON;
00249
00250 Vector4 ambientColor(0.2f, 0.2f, 0.2f, 0.8f);
00251 Vector4 diffuseColor(0.8f, 0.8f, 0.8f, 0.8f);
00252 Vector4 specularColor(1.0f, 1.0f, 1.0f, 0.8f);
00253 Vector4 emissiveColor(0.0f, 0.0f, 0.0f, 0.8f);
00254 float shininess = 100.0f;
00255 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientColor);
00256 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuseColor);
00257 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularColor);
00258 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emissiveColor);
00259 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
00260
00261 Landscape::instance()->getSky().getSun().setLightPosition();
00262 }
00263
00264 if (!OptionsDisplay::instance()->getUseWaterTexture())
00265 {
00266 GLState currentState(GLState::LIGHTING_OFF | GLState::TEXTURE_OFF);
00267 glColor3f(0.0f, 0.3f, 1.0f);
00268 drawWater(water2, 0);
00269 }
00270 else if (GLStateExtension::hasCubeMap())
00271 {
00272 GLState currentState(state | GLState::TEXTURE_OFF | GLState::BLEND_ON | GLState::CUBEMAP_ON);
00273
00274
00275 glEnable(GL_TEXTURE_GEN_S);
00276 glEnable(GL_TEXTURE_GEN_T);
00277 glEnable(GL_TEXTURE_GEN_R);
00278 glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
00279 glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
00280 glTexGenf(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP_EXT);
00281
00282 drawWater(water2, 0);
00283 }
00284 else if (GLStateExtension::hasSphereMap())
00285 {
00286 GLState currentState(state | GLState::TEXTURE_ON | GLState::BLEND_ON);
00287 noShaderWaterTexture_->draw();
00288
00289
00290 glEnable(GL_TEXTURE_GEN_S);
00291 glEnable(GL_TEXTURE_GEN_T);
00292 glEnable(GL_TEXTURE_GEN_R);
00293 glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
00294 glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
00295 glTexGenf(GL_R, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
00296
00297 drawWater(water2, 0);
00298 }
00299 else
00300 {
00301 GLState currentState(state | GLState::TEXTURE_ON | GLState::BLEND_ON);
00302 noShaderWaterTexture_->draw();
00303
00304
00305 glEnable(GL_TEXTURE_GEN_S);
00306 glEnable(GL_TEXTURE_GEN_T);
00307 glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
00308 glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
00309 glTexGenfv(GL_S, GL_OBJECT_PLANE, PlaneS);
00310 glTexGenfv(GL_T, GL_OBJECT_PLANE, PlaneT);
00311
00312 drawWater(water2, 0);
00313 }
00314
00315 if (GLStateExtension::hasMultiTex())
00316 {
00317 glActiveTextureARB(GL_TEXTURE1);
00318 glDisable(GL_TEXTURE_GEN_S);
00319 glDisable(GL_TEXTURE_GEN_T);
00320 glDisable(GL_TEXTURE_GEN_R);
00321 glDisable(GL_TEXTURE_2D);
00322
00323 glActiveTextureARB(GL_TEXTURE0);
00324 glDisable(GL_TEXTURE_GEN_S);
00325 glDisable(GL_TEXTURE_GEN_T);
00326 glDisable(GL_TEXTURE_GEN_R);
00327 }
00328
00329 glPopAttrib();
00330 }
00331
00332 void Water2Renderer::drawWater(Water2 &water2, GLSLShaderSetup *waterShader)
00333 {
00334
00335 Vector &cameraPos = GLCamera::getCurrentCamera()->getCurrentPos();
00336 VisibilityPatchGrid::instance()->drawWater(
00337 *currentPatch_, water2.getIndexs(), cameraPos, landscapeSize_, waterShader);
00338 }
00339
00340 void Water2Renderer::generate(LandscapeTexBorderWater *water, ProgressCounter *counter)
00341 {
00342 currentPatch_ = 0;
00343 if (GLStateExtension::hasShaders())
00344 {
00345
00346 if (!waterShader_)
00347 {
00348 GLSLShader::defines_list dl;
00349 if (Landscape::instance()->getShadowFrameBuffer().bufferValid())
00350 {
00351 dl.push_back("USE_SHADOWS");
00352 }
00353
00354 if (OptionsDisplay::instance()->getSimpleWaterShaders())
00355 {
00356 waterShader_ = new GLSLShaderSetup(
00357 S3D::getDataFile("data/shaders/watersimple.vshader"),
00358 S3D::getDataFile("data/shaders/watersimple.fshader"),
00359 dl);
00360 }
00361 else
00362 {
00363 waterShader_ = new GLSLShaderSetup(
00364 S3D::getDataFile("data/shaders/water.vshader"),
00365 S3D::getDataFile("data/shaders/water.fshader"),
00366 dl);
00367 }
00368 }
00369 }
00370
00371
00372 waterHeight_ = water->height.asFloat();
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384 Vector4 light_color(water->wavelight, 1.0f);
00385 Vector4 wavetopA(water->wavetopa, 0.0f);
00386 Vector4 wavetopB(water->wavetopb, 0.0f);
00387 Vector4 wavebottomA(water->wavebottoma, 0.0f);
00388 Vector4 wavebottomB(water->wavebottomb, 0.0f);
00389 Vector4 wavetop = light_color.lerp(wavetopA, wavetopB);
00390 Vector4 wavebottom = light_color.lerp(wavebottomA, wavebottomB);
00391
00392
00393 if (GLStateExtension::hasFBO() &&
00394 GLStateExtension::hasShaders() &&
00395 !OptionsDisplay::instance()->getNoWaterReflections())
00396 {
00397 reflectionTexture_.createBufferTexture(512, 512, false);
00398 reflectionBuffer_.create(reflectionTexture_, true);
00399 }
00400 else
00401 {
00402 ImageHandle loadedBitmapWater =
00403 ImageFactory::loadImageHandle(S3D::getDataFile(water->texture.c_str()));
00404 ImageHandle bitmapWater2 = loadedBitmapWater.createResize(128, 128);
00405 reflectionTexture_.create(bitmapWater2, true);
00406 }
00407
00408 ImageHandle map = ImageFactory::createBlank(128, 128, false, 0);
00409 normalTexture_.create(map, GLStateExtension::hasHardwareMipmaps());
00410
00411 LandscapeDefn &defn = *ScorchedClient::instance()->getLandscapeMaps().
00412 getDefinitions().getDefn();
00413 landscapeSize_ = Vector(defn.getLandscapeWidth(), defn.getLandscapeHeight());
00414
00415 if (GLStateExtension::hasShaders())
00416 {
00417 Vector upwelltop(wavetop[0], wavetop[1], wavetop[2]);
00418 Vector upwellbot(wavebottom[0], wavebottom[1], wavebottom[2]);
00419 Vector upwelltopbot = upwelltop - upwellbot;
00420
00421 waterShader_->use();
00422 waterShader_->set_uniform("upwelltop", upwelltop);
00423 waterShader_->set_uniform("upwellbot", upwellbot);
00424 waterShader_->set_uniform("upwelltopbot", upwelltopbot);
00425 if (!OptionsDisplay::instance()->getSimpleWaterShaders())
00426 {
00427 Vector landfoam;
00428 waterShader_->set_uniform("landfoam", landfoam);
00429 waterShader_->set_uniform("landscape_size", landscapeSize_);
00430 }
00431 waterShader_->use_fixed();
00432 }
00433 else
00434 {
00435
00436
00437 ImageHandle loadedBitmapWater =
00438 ImageFactory::loadImageHandle(S3D::getDataFile(water->reflection.c_str()));
00439 ImageHandle bitmapWater2 = loadedBitmapWater.createResize(256, 256);
00440 delete noShaderWaterTexture_;
00441 if (GLStateExtension::hasCubeMap())
00442 {
00443 GLTextureCubeMap *waterCubeMap = new GLTextureCubeMap();
00444 waterCubeMap->create(bitmapWater2, false);
00445 noShaderWaterTexture_ = waterCubeMap;
00446 }
00447 else
00448 {
00449 GLTexture *waterNormalMap = new GLTexture();
00450 waterNormalMap->create(bitmapWater2, false);
00451 noShaderWaterTexture_ = waterNormalMap;
00452 }
00453 }
00454
00455
00456 windSpeed1_ = ScorchedClient::instance()->
00457 getOptionsTransient().getWindSpeed().asFloat() * 2.0f + 3.0f;
00458 windDir1_ = ScorchedClient::instance()->
00459 getOptionsTransient().getWindDirection().asVector();
00460 windDir1_[2] = 0.0f;
00461 windSpeed2_ = MAX(0.0f, RAND * 2.0f - 1.0f + windSpeed1_);
00462 windDir2_ = Vector(windDir1_[0] + RAND * 0.4f - 0.2f,
00463 windDir1_[1] + RAND * 0.4f - 0.2f);
00464 windDir1_.StoreNormalize();
00465 windDir2_.StoreNormalize();
00466 }