00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <landscape/Landscape.h>
00022 #include <landscape/LandscapePoints.h>
00023 #include <landscapemap/LandscapeMaps.h>
00024 #include <landscape/LandscapeSoundManager.h>
00025 #include <landscape/LandscapeMusicManager.h>
00026 #include <landscape/Smoke.h>
00027 #include <landscape/Wall.h>
00028 #include <landscape/ShadowMap.h>
00029 #include <landscape/InfoMap.h>
00030 #include <landscape/GraphicalLandscapeMap.h>
00031 #include <landscapedef/LandscapeTex.h>
00032 #include <landscapedef/LandscapeDefn.h>
00033 #include <landscapedef/LandscapeDefinition.h>
00034 #include <landscapedef/LandscapeDefinitions.h>
00035 #include <lang/LangResource.h>
00036 #include <sky/Sky.h>
00037 #include <water/Water.h>
00038 #include <land/VisibilityPatchGrid.h>
00039 #include <movement/TargetMovement.h>
00040 #include <image/ImageFactory.h>
00041 #include <image/ImageBitmap.h>
00042 #include <GLEXT/GLImageModifier.h>
00043 #include <GLEXT/GLStateExtension.h>
00044 #include <GLEXT/GLCameraFrustum.h>
00045 #include <console/ConsoleRuleMethodIAdapter.h>
00046 #include <GLSL/GLSLShaderSetup.h>
00047 #include <common/OptionsTransient.h>
00048 #include <common/Defines.h>
00049 #include <graph/OptionsDisplay.h>
00050 #include <graph/MainCamera.h>
00051 #include <sound/Sound.h>
00052 #include <client/ScorchedClient.h>
00053 #include <dialogs/CameraDialog.h>
00054 #include <engine/ActionController.h>
00055 #include <tankgraph/RenderTargets.h>
00056 #include <time.h>
00057
00058 Landscape *Landscape::instance_ = 0;
00059
00060 Landscape *Landscape::instance()
00061 {
00062 if (!instance_)
00063 {
00064 instance_ = new Landscape;
00065 }
00066 return instance_;
00067 }
00068
00069 Landscape::Landscape() :
00070 resetLandscape_(false), resetLandscapeTimer_(0.0f),
00071 textureType_(eDefault),
00072 changeCount_(1),
00073 landShader_(0)
00074 {
00075 water_ = new Water();
00076 points_ = new LandscapePoints();
00077 sky_ = new Sky();
00078 smoke_ = new Smoke();
00079 wall_ = new Wall();
00080
00081 new ConsoleRuleMethodIAdapter<Landscape>(
00082 this, &Landscape::savePlan, "SavePlan");
00083 }
00084
00085 Landscape::~Landscape()
00086 {
00087 }
00088
00089 void Landscape::simulate(float frameTime)
00090 {
00091 if (resetLandscape_)
00092 {
00093 resetLandscapeTimer_ -= frameTime;
00094 if (resetLandscapeTimer_ < 0.0f)
00095 {
00096
00097 updatePlanATexture();
00098 updatePlanTexture();
00099
00100
00101 GraphicalLandscapeMap *landscapeMap = (GraphicalLandscapeMap *)
00102 ScorchedClient::instance()->getLandscapeMaps().
00103 getGroundMaps().getHeightMap().getGraphicalMap();
00104 landscapeMap->updateWholeBuffer();
00105
00106
00107 changeCount_++;
00108 resetLandscape_ = false;
00109 }
00110 }
00111
00112 float speedMult = ScorchedClient::instance()->
00113 getActionController().getFast().asFloat();
00114 water_->simulate(frameTime * speedMult);
00115 sky_->simulate(frameTime * speedMult);
00116 wall_->simulate(frameTime * speedMult);
00117 LandscapeSoundManager::instance()->simulate(frameTime * speedMult);
00118 }
00119
00120 void Landscape::recalculate()
00121 {
00122 if (!resetLandscape_)
00123 {
00124 resetLandscape_ = true;
00125 resetLandscapeTimer_ = 1.0f;
00126 }
00127 }
00128
00129 void Landscape::reset(ProgressCounter *counter)
00130 {
00131 changeCount_++;
00132
00133
00134
00135 ScorchedClient::instance()->
00136 getParticleEngine().killAll();
00137 MainCamera::instance()->getTarget().
00138 getPrecipitationEngine().killAll();
00139 CameraDialog::instance()->getCamera().
00140 getPrecipitationEngine().killAll();
00141 }
00142
00143 void Landscape::drawShadows()
00144 {
00145 if (!GLStateExtension::hasHardwareShadows()) return;
00146
00147 GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "LANDSCAPE_SHADOWS_PRE");
00148
00149
00150 GLState glstate(GLState::TEXTURE_OFF | GLState::DEPTH_ON);
00151
00152 float landWidth = ScorchedClient::instance()->getLandscapeMaps().
00153 getGroundMaps().getLandscapeWidth() / 2.0f;
00154 float landHeight = ScorchedClient::instance()->getLandscapeMaps().
00155 getGroundMaps().getLandscapeHeight() / 2.0f;
00156 float maxWidth = MAX(landWidth, landHeight);
00157
00158
00159 Vector sunPosition = Landscape::instance()->getSky().getSun().getPosition();
00160 sunPosition *= 0.5f + (maxWidth - 128.0f) / 256.0f;
00161
00162 Vector relativePosition = sunPosition;
00163 relativePosition[0] -= landWidth;
00164 relativePosition[1] -= landHeight;
00165 float magnitude = relativePosition.Magnitude();
00166
00167
00168 shadowFrameBuffer_.bind();
00169 glViewport(0, 0, shadowFrameBuffer_.getWidth(), shadowFrameBuffer_.getHeight());
00170
00171
00172 glMatrixMode(GL_PROJECTION);
00173 glLoadIdentity();
00174 gluPerspective(60.0f, 1.0f, magnitude - (maxWidth * 1.5f), magnitude + (maxWidth * 1.5f));
00175 glMatrixMode(GL_MODELVIEW);
00176 glLoadIdentity();
00177 gluLookAt(
00178 sunPosition[0], sunPosition[1], sunPosition[2],
00179 landWidth, landHeight, 0.0f ,
00180 0.0f, 0.0f, 1.0f);
00181
00182 GLCameraFrustum::instance()->draw(0);
00183
00184
00185 glGetFloatv(GL_MODELVIEW_MATRIX, lightModelMatrix_);
00186 glGetFloatv(GL_PROJECTION_MATRIX, lightProjMatrix_);
00187
00188
00189 glClear(GL_DEPTH_BUFFER_BIT);
00190
00191
00192 glPolygonOffset(10.0f, 10.0f);
00193 glEnable(GL_POLYGON_OFFSET_FILL);
00194
00195
00196 glColorMask(0, 0, 0, 0);
00197
00198
00199 GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "LANDSCAPE_SHADOWS_PRE");
00200
00201 GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "LANDSCAPE_SHADOWS_DRAW_LAND");
00202 VisibilityPatchGrid::instance()->drawLand(0, true);
00203 GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "LANDSCAPE_SHADOWS_DRAW_LAND");
00204
00205 if (!OptionsDisplay::instance()->getNoGLObjectShadows())
00206 {
00207 RenderTargets::instance()->shadowDraw();
00208 }
00209
00210 GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "LANDSCAPE_SHADOWS_POST");
00211
00212 static bool createdMap = false;
00213 if (OptionsDisplay::instance()->getDrawGraphicalShadowMap())
00214 {
00215 if (!createdMap)
00216 {
00217 createdMap = true;
00218
00219 static float *depthResult =
00220 new float[shadowFrameBuffer_.getWidth() * shadowFrameBuffer_.getHeight()];
00221 static ImageHandle depthImage =
00222 ImageFactory::createBlank(shadowFrameBuffer_.getWidth(),
00223 shadowFrameBuffer_.getHeight());
00224
00225 glReadPixels(0, 0,
00226 shadowFrameBuffer_.getWidth(), shadowFrameBuffer_.getHeight(),
00227 GL_DEPTH_COMPONENT, GL_FLOAT, depthResult);
00228
00229 float min = 1.0, max = 0.0;
00230 float *src = depthResult;
00231 unsigned char *dest = depthImage.getBits();
00232 for (int i=0; i<shadowFrameBuffer_.getWidth() * shadowFrameBuffer_.getHeight(); i++, src++, dest+=3)
00233 {
00234 if (*src != 1.0f)
00235 {
00236 if (*src != 0.0f)
00237 {
00238 min = MIN(min, *src);
00239 max = MAX(max, *src);
00240 }
00241
00242
00243 dest[0] = (unsigned char) (*src * 255.0f);
00244 dest[1] = (unsigned char) (*src * 255.0f);
00245 dest[2] = (unsigned char) (*src * 255.0f);
00246 }
00247 }
00248
00249 colorDepthMap_.replace(depthImage);
00250 }
00251 }
00252 else
00253 {
00254 createdMap = false;
00255 }
00256
00257
00258 glColorMask(1, 1, 1, 1);
00259
00260
00261 glDisable(GL_POLYGON_OFFSET_FILL);
00262
00263
00264 shadowFrameBuffer_.unBind();
00265
00266
00267 MainCamera::instance()->getCamera().draw();
00268 GLCameraFrustum::instance()->draw(0);
00269
00270 GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "LANDSCAPE_SHADOWS_POST");
00271 }
00272
00273 void Landscape::drawSetup()
00274 {
00275 if (OptionsDisplay::instance()->getDrawLines()) glPolygonMode(GL_FRONT, GL_LINE);
00276
00277
00278
00279 if (!OptionsDisplay::instance()->getNoFog())
00280 {
00281 glEnable(GL_FOG);
00282 }
00283 }
00284
00285 void Landscape::drawTearDown()
00286 {
00287 glDisable(GL_FOG);
00288 if (OptionsDisplay::instance()->getDrawLines()) glPolygonMode(GL_FRONT, GL_FILL);
00289 }
00290
00291 void Landscape::drawLand()
00292 {
00293 drawSetup();
00294
00295 GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "LANDSCAPE_LOD");
00296 VisibilityPatchGrid::instance()->calculateVisibility();
00297 GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "LANDSCAPE_LOD");
00298
00299 GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "LANDSCAPE_SKY");
00300 sky_->drawBackdrop();
00301 GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "LANDSCAPE_SKY");
00302
00303 if (OptionsDisplay::instance()->getDrawLandscape())
00304 {
00305 if (GLStateExtension::hasHardwareShadows() &&
00306 OptionsDisplay::instance()->getUseLandscapeTexture())
00307 {
00308 actualDrawLandShader();
00309 }
00310 else
00311 {
00312 actualDrawLandTextured();
00313 }
00314 }
00315
00316 if (OptionsDisplay::instance()->getDrawGraphicalShadowMap())
00317 {
00318 drawGraphicalShadowMap();
00319 }
00320 if (OptionsDisplay::instance()->getDrawGraphicalReflectionMap())
00321 {
00322 drawGraphicalReflectionMap();
00323 }
00324
00325 GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "LANDSCAPE_POINTS");
00326 points_->draw();
00327 GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "LANDSCAPE_POINTS");
00328
00329 if (OptionsDisplay::instance()->getDrawMovement())
00330 {
00331 ScorchedClient::instance()->getTargetMovement().draw();
00332 }
00333
00334 drawTearDown();
00335 }
00336
00337 void Landscape::drawWater()
00338 {
00339 if (!water_->getWaterOn()) return;
00340
00341 if (GLStateExtension::hasFBO() &&
00342 GLStateExtension::hasShaders() &&
00343 !OptionsDisplay::instance()->getNoWaterReflections() &&
00344 OptionsDisplay::instance()->getDrawWater() &&
00345 water_->getWaterOn())
00346 {
00347 GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "WATER_REFLECTIONS");
00348
00349 water_->bindWaterReflection();
00350
00351 glClearColor(0, 1.0f/16.0f, 1.0f/8.0f, 0);
00352 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
00353
00354 glPushMatrix();
00355
00356 glTranslatef(0.0f, 0.0f, water_->getWaterHeight() * 2.0f);
00357
00358
00359 glScalef(1.0f, 1.0f, -1.0f);
00360 glCullFace(GL_FRONT);
00361
00362 drawSetup();
00363 sky_->drawBackdrop();
00364 sky_->drawLayers();
00365 actualDrawLandReflection();
00366 drawTearDown();
00367
00368
00369
00370 glCullFace(GL_BACK);
00371 glPopMatrix();
00372
00373 water_->unBindWaterReflection();
00374
00375 GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "WATER_REFLECTIONS");
00376 }
00377
00378 drawSetup();
00379
00380 water_->draw();
00381
00382 drawTearDown();
00383 }
00384
00385 void Landscape::drawObjects()
00386 {
00387 drawSetup();
00388
00389 wall_->draw();
00390 sky_->drawLayers();
00391
00392 drawTearDown();
00393 }
00394
00395 int Landscape::getPlanTexSize()
00396 {
00397 switch (OptionsDisplay::instance()->getTexSize())
00398 {
00399 case 0:
00400 return 64;
00401 break;
00402 case 2:
00403 return 256;
00404 break;
00405 default:
00406 return 128;
00407 break;
00408 }
00409 return 128;
00410 }
00411
00412 int Landscape::getMapTexSize()
00413 {
00414 switch (OptionsDisplay::instance()->getTexSize())
00415 {
00416 case 0:
00417 return 256;
00418 break;
00419 case 2:
00420 return 2048;
00421 break;
00422 default:
00423 return 1024;
00424 break;
00425 }
00426 return 1024;
00427 }
00428
00429 void Landscape::generate(ProgressCounter *counter)
00430 {
00431 GraphicalLandscapeMap *landscapeMap = (GraphicalLandscapeMap *)
00432 ScorchedClient::instance()->getLandscapeMaps().
00433 getGroundMaps().getHeightMap().getGraphicalMap();
00434 landscapeMap->updateWholeBuffer();
00435
00436 textureType_ = eDefault;
00437 InfoMap::instance()->addAdapters();
00438
00439
00440 int mapTexSize = getMapTexSize();
00441 int planTexSize = getPlanTexSize();
00442
00443
00444 if (!mainMap_.getBits())
00445 {
00446 mainMap_ = ImageFactory::createBlank(mapTexSize, mapTexSize);
00447 bitmapPlanAlpha_ = ImageFactory::createBlank(planTexSize, planTexSize, true);
00448 bitmapPlan_ = ImageFactory::createBlank(planTexSize, planTexSize);
00449 bitmapPlanAlphaAlpha_ = ImageFactory::createBlank(planTexSize, planTexSize, false, 0);
00450 splatMap_ = ImageFactory::createBlank(1024, 1024);
00451 }
00452
00453 ImageHandle splatMask1 = ImageFactory::createBlank(mapTexSize, mapTexSize, true, 0);
00454 ImageHandle splatMask2 = ImageFactory::createBlank(mapTexSize, mapTexSize, true, 0);
00455 ImageHandle splatMaskBorder1 = ImageFactory::createBlank(64, 64, true, 0);
00456 ImageHandle splatMaskBorder2 = ImageFactory::createBlank(64, 64, true, 0);
00457 ImageModifier::redBitmap(splatMaskBorder1);
00458
00459 if (GLStateExtension::hasHardwareShadows())
00460 {
00461 if (!shadowFrameBuffer_.bufferValid())
00462 {
00463
00464 if (!shadowFrameBuffer_.create(2048, 2048))
00465 {
00466 S3D::dialogExit("Scorched3D", "Failed to create shadow frame buffer");
00467 }
00468 }
00469 }
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479 LandscapeDefn *defn =
00480 ScorchedClient::instance()->getLandscapeMaps().getDefinitions().getDefn();
00481 LandscapeTex *tex =
00482 ScorchedClient::instance()->getLandscapeMaps().getDefinitions().getTex();
00483 if (tex->texture->getType() == LandscapeTexType::eTextureGenerate)
00484 {
00485 LandscapeTexTextureGenerate *generate =
00486 (LandscapeTexTextureGenerate *) tex->texture;
00487
00488 ImageHandle texture0 =
00489 ImageFactory::loadImageHandle(S3D::getDataFile(generate->texture0.c_str()));
00490 ImageHandle texture1 =
00491 ImageFactory::loadImageHandle(S3D::getDataFile(generate->texture1.c_str()));
00492 ImageHandle texture2 =
00493 ImageFactory::loadImageHandle(S3D::getDataFile(generate->texture2.c_str()));
00494 ImageHandle texture3 =
00495 ImageFactory::loadImageHandle(S3D::getDataFile(generate->texture3.c_str()));
00496 ImageHandle bitmapShore =
00497 ImageFactory::loadImageHandle(S3D::getDataFile(generate->shore.c_str()));
00498 ImageHandle bitmapRock =
00499 ImageFactory::loadImageHandle(S3D::getDataFile(generate->rockside.c_str()));
00500 ImageHandle bitmapRoof =
00501 ImageFactory::loadImageHandle(S3D::getDataFile(generate->roof.c_str()));
00502 Image *bitmaps[4];
00503 bitmaps[0] = &texture0;
00504 bitmaps[1] = &texture1;
00505 bitmaps[2] = &texture2;
00506 bitmaps[3] = &texture3;
00507
00508
00509 if (counter) counter->setNewOp(LANG_RESOURCE("LANDSCAPE_MAP", "Landscape Map"));
00510 ImageModifier::addHeightToBitmap(
00511 ScorchedClient::instance()->getLandscapeMaps().getGroundMaps().getHeightMap(),
00512 mainMap_, splatMask1, splatMask2,
00513 bitmapRock, bitmapShore, bitmaps, 4, 1024, counter);
00514
00515 #ifdef SPLAT_MAP
00516
00517 ImageModifier::addTexturesToBitmap(
00518 splatMap_,
00519 bitmapRock, bitmapShore, bitmaps, 4);
00520 splatTextures_.create(splatMap_, false);
00521
00522
00523 splatMaskTexture1_.replace(splatMask1, false);
00524 splatMaskTexture2_.replace(splatMask2, false);
00525 splatMaskTextureBorder1_.replace(splatMaskBorder1, false);
00526 splatMaskTextureBorder2_.replace(splatMaskBorder2, false);
00527 #endif
00528
00529
00530 groundTexture_.replace(texture0, false);
00531 roofTexture_.replace(bitmapRoof, true);
00532 }
00533 else
00534 {
00535 S3D::dialogExit("Landscape", S3D::formatStringBuffer(
00536 "Failed to find heightmap type %i",
00537 tex->texture->getType()));
00538 }
00539
00540 points_->generate();
00541
00542
00543 sky_->getSun().setPosition(tex->skysunxy, tex->skysunyz);
00544 if (!GLStateExtension::hasHardwareShadows())
00545 {
00546 Vector sunPos = sky_->getSun().getPosition();
00547 ImageModifier::addLightMapToBitmap(mainMap_,
00548 ScorchedClient::instance()->getLandscapeMaps().getGroundMaps().getHeightMap(),
00549 sunPos,
00550 tex->skyambience, tex->skydiffuse, counter);
00551 }
00552 else
00553 {
00554
00555 if (!landShader_)
00556 {
00557 landShader_ = new GLSLShaderSetup(
00558 S3D::getDataFile("data/shaders/land.vshader"),
00559 S3D::getDataFile("data/shaders/land.fshader"));
00560 }
00561 }
00562
00563
00564 std::list<PlacementShadowDefinition::Entry> &shadows =
00565 ScorchedClient::instance()->getLandscapeMaps().getGroundMaps().
00566 getGroups().getShadows();
00567 std::list<PlacementShadowDefinition::Entry>::iterator itor;
00568 for (itor = shadows.begin();
00569 itor != shadows.end();
00570 itor++)
00571 {
00572 PlacementShadowDefinition::Entry &entry = (*itor);
00573
00574 entry.definition_->updateLandscapeTexture(
00575 !GLStateExtension::hasHardwareShadows() ||
00576 OptionsDisplay::instance()->getNoGLObjectShadows(),
00577 ScorchedClient::instance()->getContext(),
00578 entry.position_, entry.size_);
00579 }
00580
00581
00582 DIALOG_ASSERT(texture_.replace(mainMap_, false));
00583
00584
00585 gluScaleImage(
00586 GL_RGB,
00587 mainMap_.getWidth(), mainMap_.getHeight(),
00588 GL_UNSIGNED_BYTE, mainMap_.getBits(),
00589 bitmapPlan_.getWidth(), bitmapPlan_.getHeight(),
00590 GL_UNSIGNED_BYTE, bitmapPlan_.getBits());
00591
00592
00593 std::string sprayMaskFile = S3D::getDataFile("data/textures/smoke01.bmp");
00594 ImageHandle sprayMaskBitmap =
00595 ImageFactory::loadImageHandle(sprayMaskFile.c_str(), sprayMaskFile.c_str(), false);
00596 scorchMap_ =
00597 ImageFactory::loadImageHandle(S3D::getDataFile(tex->scorch.c_str()));
00598 ImageHandle scorchMap = scorchMap_.createResize(
00599 sprayMaskBitmap.getWidth(), sprayMaskBitmap.getHeight());
00600 ImageHandle texture1New = ImageFactory::createBlank(sprayMaskBitmap.getWidth(), sprayMaskBitmap.getHeight(), true);
00601 ImageModifier::makeBitmapTransparent(texture1New, scorchMap, sprayMaskBitmap);
00602 landTex1_.replace(texture1New);
00603
00604
00605 ImageHandle arenaBitmap = ImageModifier::makeArenaBitmap();
00606 DIALOG_ASSERT(arenaMainTexture_.replace(arenaBitmap));
00607 arenaMainTexture_.draw();
00608 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
00609 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
00610 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
00611 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
00612 ImageHandle arenaSurroundBitmap = ImageModifier::makeArenaSurroundBitmap();
00613 DIALOG_ASSERT(arenaSurroundTexture_.replace(arenaSurroundBitmap));
00614
00615
00616 ImageHandle bitmapMagma =
00617 ImageFactory::loadImageHandle(S3D::getDataFile(tex->magmasmall.c_str()));
00618 DIALOG_ASSERT(magTexture_.replace(bitmapMagma));
00619
00620
00621 ImageHandle bitmapDetail =
00622 ImageFactory::loadImageHandle(S3D::getDataFile(tex->detail.c_str()));
00623 DIALOG_ASSERT(detailTexture_.replace(bitmapDetail, true));
00624
00625
00626 GLfloat fogColorF[4];
00627 fogColorF[0] = tex->fog[0];
00628 fogColorF[1] = tex->fog[1];
00629 fogColorF[2] = tex->fog[2];
00630 fogColorF[3] = 1.0f;
00631 glFogfv(GL_FOG_COLOR, fogColorF);
00632 GLfloat fogDensity = tex->fogdensity;
00633 glFogf(GL_FOG_DENSITY, fogDensity);
00634
00635
00636 sky_->generate();
00637
00638
00639 water_->generate(counter);
00640
00641
00642 updatePlanTexture();
00643 updatePlanATexture();
00644
00645
00646 LandscapeSoundManager::instance()->addSounds();
00647 LandscapeMusicManager::instance()->addMusics();
00648 }
00649
00650 void Landscape::updatePlanTexture()
00651 {
00652 if (water_->getWaterOn())
00653 {
00654 ImageModifier::addWaterToBitmap(
00655 ScorchedClient::instance()->getLandscapeMaps().getGroundMaps().getHeightMap(),
00656 bitmapPlan_, water_->getWaterBitmap(), water_->getWaterHeight());
00657 }
00658
00659 DIALOG_ASSERT(planTexture_.replace(bitmapPlan_, false));
00660 }
00661
00662 void Landscape::actualDrawLandTextured()
00663 {
00664 unsigned int state = 0;
00665 if (!OptionsDisplay::instance()->getUseLandscapeTexture()) state |= GLState::TEXTURE_OFF;
00666
00667 GLState glState(state);
00668
00669 bool showArenaArea = (!OptionsDisplay::instance()->getNoArenaMoveVisibility() &&
00670 MainCamera::instance()->getCameraSelected()) ||
00671 MainCamera::instance()->getShowArena();
00672
00673 bool useDetail =
00674 GLStateExtension::getTextureUnits() > 2 &&
00675 OptionsDisplay::instance()->getDetailTexture() &&
00676 GLStateExtension::hasEnvCombine();
00677
00678 if (OptionsDisplay::instance()->getUseLandscapeTexture())
00679 {
00680 if (GLStateExtension::hasMultiTex())
00681 {
00682 if (useDetail)
00683 {
00684 glActiveTextureARB(GL_TEXTURE2_ARB);
00685 glEnable(GL_TEXTURE_2D);
00686 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);
00687 glTexEnvi(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2);
00688
00689 detailTexture_.draw(true);
00690 }
00691
00692 glActiveTextureARB(GL_TEXTURE1_ARB);
00693 glEnable(GL_TEXTURE_2D);
00694 if (showArenaArea)
00695 {
00696 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
00697 arenaMainTexture_.draw();
00698 }
00699 else getShadowMap().setTexture();
00700
00701 glActiveTextureARB(GL_TEXTURE0_ARB);
00702 }
00703
00704 texture_.draw(true);
00705 }
00706
00707 glColor3f(1.0f, 1.0f, 1.0f);
00708 GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "LANDSCAPE_LAND");
00709 VisibilityPatchGrid::instance()->drawLand();
00710 GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "LANDSCAPE_LAND");
00711 if (OptionsDisplay::instance()->getDrawLandLOD())
00712 {
00713 VisibilityPatchGrid::instance()->drawLandLODLevels();
00714 }
00715
00716 if (OptionsDisplay::instance()->getUseLandscapeTexture())
00717 {
00718 if (GLStateExtension::hasMultiTex())
00719 {
00720 glActiveTextureARB(GL_TEXTURE1_ARB);
00721 if (showArenaArea) arenaSurroundTexture_.draw();
00722 else glEnable(GL_TEXTURE_2D);
00723
00724 glActiveTextureARB(GL_TEXTURE0_ARB);
00725 }
00726
00727 groundTexture_.draw(true);
00728 }
00729
00730 if (OptionsDisplay::instance()->getDrawSurround())
00731 {
00732 GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "LANDSCAPE_SURROUND");
00733 VisibilityPatchGrid::instance()->drawSurround();
00734 GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "LANDSCAPE_SURROUND");
00735 }
00736
00737 if (OptionsDisplay::instance()->getUseLandscapeTexture())
00738 {
00739 if (GLStateExtension::hasMultiTex())
00740 {
00741 if (useDetail)
00742 {
00743 glActiveTextureARB(GL_TEXTURE2_ARB);
00744 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00745 glDisable(GL_TEXTURE_2D);
00746 }
00747
00748 glActiveTextureARB(GL_TEXTURE1_ARB);
00749 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
00750 glDisable(GL_TEXTURE_2D);
00751 glActiveTextureARB(GL_TEXTURE0_ARB);
00752 }
00753 }
00754 }
00755
00756 void Landscape::actualDrawLandReflection()
00757 {
00758 unsigned int state = GLState::BLEND_ON | GLState::LIGHTING_ON | GLState::LIGHT1_ON;
00759 if (!OptionsDisplay::instance()->getUseLandscapeTexture()) state |= GLState::TEXTURE_OFF;
00760 GLState glState(state);
00761
00762 Vector4 ambientColor(1.0f, 1.0f, 1.0f, 1.0f);
00763 Vector4 diffuseColor(0.0f, 0.0f, 0.0f, 1.0f);
00764 Vector4 specularColor(1.0f, 1.0f, 1.0f, 1.0f);
00765 Vector4 emissiveColor(0.0f, 0.0f, 0.0f, 1.0f);
00766 float shininess = 1.0f;
00767 glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, ambientColor);
00768 glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, diffuseColor);
00769 glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, specularColor);
00770 glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, emissiveColor);
00771 glMaterialf(GL_FRONT_AND_BACK, GL_SHININESS, shininess);
00772
00773 Landscape::instance()->getSky().getSun().setLightPosition();
00774
00775 if (OptionsDisplay::instance()->getUseLandscapeTexture())
00776 {
00777 planAlphaTexture_.draw(true);
00778 }
00779
00780 glColor3f(1.0f, 1.0f, 1.0f);
00781 VisibilityPatchGrid::instance()->drawLand(2);
00782 }
00783
00784 void Landscape::createShadowMatrix()
00785 {
00786 if (!GLStateExtension::hasHardwareShadows()) return;
00787
00788
00789 static const float mNormalizeMatrix[] =
00790 {
00791 0.5f, 0.0f, 0.0f, 0.0f,
00792 0.0f, 0.5f, 0.0f, 0.0f,
00793 0.0f, 0.0f, 0.5f, 0.0f,
00794 0.5f, 0.5f, 0.5f, 1.0f
00795 };
00796 static GLfloat modelMatrix[16], modelMatrixI[16];
00797 glGetFloatv(GL_MODELVIEW_MATRIX, modelMatrix);
00798
00799
00800 modelMatrixI[ 0] = modelMatrix[ 0];
00801 modelMatrixI[ 4] = modelMatrix[ 1];
00802 modelMatrixI[ 8] = modelMatrix[ 2];
00803 modelMatrixI[ 1] = modelMatrix[ 4];
00804 modelMatrixI[ 5] = modelMatrix[ 5];
00805 modelMatrixI[ 9] = modelMatrix[ 6];
00806 modelMatrixI[ 2] = modelMatrix[ 8];
00807 modelMatrixI[ 6] = modelMatrix[ 9];
00808 modelMatrixI[10] = modelMatrix[10];
00809 modelMatrixI[ 3] = 0;
00810 modelMatrixI[ 7] = 0;
00811 modelMatrixI[11] = 0;
00812 modelMatrixI[15] = modelMatrix[15];
00813
00814
00815 modelMatrixI[12] = modelMatrixI[0] * -modelMatrix[12] + modelMatrixI[4] * -modelMatrix[13] + modelMatrixI[ 8] * -modelMatrix[14];
00816 modelMatrixI[13] = modelMatrixI[1] * -modelMatrix[12] + modelMatrixI[5] * -modelMatrix[13] + modelMatrixI[ 9] * -modelMatrix[14];
00817 modelMatrixI[14] = modelMatrixI[2] * -modelMatrix[12] + modelMatrixI[6] * -modelMatrix[13] + modelMatrixI[10] * -modelMatrix[14];
00818
00819
00820 glMatrixMode(GL_TEXTURE);
00821 glLoadMatrixf(mNormalizeMatrix);
00822 glMultMatrixf(lightProjMatrix_);
00823 glMultMatrixf(lightModelMatrix_);
00824 glMultMatrixf(modelMatrixI);
00825 glGetFloatv(GL_TEXTURE_MATRIX, shadowTextureMatrix_);
00826 glMatrixMode(GL_MODELVIEW);
00827 }
00828
00829 void Landscape::actualDrawLandShader()
00830 {
00831 GLState glState(GLState::TEXTURE_ON | GLState::DEPTH_ON);
00832
00833 getSky().getSun().setLightPosition(false);
00834
00835 #ifdef SPLAT_MAP
00836 landShader_->use();
00837 landShader_->set_gl_texture(splatMaskTexture1_, "splat1map", 0);
00838 landShader_->set_gl_texture(splatMaskTexture2_, "splat2map", 1);
00839 landShader_->set_gl_texture(splatTextures_, "splattex", 2);
00840 landShader_->set_gl_texture(shadowFrameBuffer_, "shadow", 3);
00841 #else
00842 landShader_->use();
00843 landShader_->set_gl_texture(texture_, "mainmap", 0);
00844 landShader_->set_gl_texture(detailTexture_, "detailmap", 1);
00845 landShader_->set_gl_texture(arenaMainTexture_, "arenamap", 3);
00846
00847 bool showArenaArea = (!OptionsDisplay::instance()->getNoArenaMoveVisibility() &&
00848 MainCamera::instance()->getCameraSelected()) ||
00849 MainCamera::instance()->getShowArena();
00850 landShader_->set_uniform("showarena", showArenaArea?1.0f:0.0f);
00851
00852 glActiveTextureARB(GL_TEXTURE2_ARB);
00853 glEnable(GL_TEXTURE_2D);
00854 landShader_->set_gl_texture(shadowFrameBuffer_, "shadow", 2);
00855 glMatrixMode(GL_TEXTURE);
00856 createShadowMatrix();
00857 glMatrixMode(GL_MODELVIEW);
00858 glActiveTextureARB(GL_TEXTURE0_ARB);
00859 #endif
00860
00861 glColor3f(1.0f, 1.0f, 1.0f);
00862
00863
00864 GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "LANDSCAPE_LAND");
00865 VisibilityPatchGrid::instance()->drawLand();
00866 GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "LANDSCAPE_LAND");
00867
00868
00869 if (OptionsDisplay::instance()->getDrawSurround())
00870 {
00871 GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "LANDSCAPE_SURROUND");
00872 #ifdef SPLAT_MAP
00873 landShader_->set_gl_texture(splatMaskTextureBorder1_, "splat1map", 0);
00874 landShader_->set_gl_texture(splatMaskTextureBorder2_, "splat2map", 1);
00875 #else
00876 if (OptionsDisplay::instance()->getDrawWater())
00877 {
00878
00879 glActiveTextureARB(GL_TEXTURE2_ARB);
00880 glMatrixMode(GL_TEXTURE);
00881 glLoadIdentity();
00882 glMatrixMode(GL_MODELVIEW);
00883 glActiveTextureARB(GL_TEXTURE0_ARB);
00884
00885 landShader_->use_fixed();
00886
00887 groundTexture_.draw(true);
00888 }
00889 else
00890 {
00891 landShader_->set_gl_texture(groundTexture_, "mainmap", 0);
00892 landShader_->set_gl_texture(arenaSurroundTexture_, "arenamap", 3);
00893 }
00894 #endif
00895 VisibilityPatchGrid::instance()->drawSurround();
00896 GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "LANDSCAPE_SURROUND");
00897 }
00898
00899
00900 glActiveTextureARB(GL_TEXTURE2_ARB);
00901 glMatrixMode(GL_TEXTURE);
00902 glLoadIdentity();
00903 glMatrixMode(GL_MODELVIEW);
00904 glActiveTextureARB(GL_TEXTURE0_ARB);
00905
00906 landShader_->use_fixed();
00907 }
00908
00909 void Landscape::drawGraphicalShadowMap()
00910 {
00911 GLState state(GLState::TEXTURE_ON);
00912
00913 glColor3f( 1.f, 1.f, 1.f );
00914 glMatrixMode(GL_PROJECTION);
00915 glPushMatrix();
00916 glLoadIdentity();
00917 gluOrtho2D(0, 800, 0, 600);
00918 glMatrixMode(GL_TEXTURE);
00919 glPushMatrix();
00920 glLoadIdentity();
00921 glMatrixMode(GL_MODELVIEW);
00922 glPushMatrix();
00923 glLoadIdentity();
00924 colorDepthMap_.draw(true);
00925 glBegin(GL_QUADS);
00926 glTexCoord2f(0.f, 0.f);
00927 glVertex2i (0, 0);
00928 glTexCoord2f(1.f, 0.f);
00929 glVertex2i (300, 0);
00930 glTexCoord2f(1.f, 1.f);
00931 glVertex2i (300, 300);
00932 glTexCoord2f(0.f, 1.f);
00933 glVertex2i (0, 300);
00934 glEnd();
00935 glMatrixMode(GL_PROJECTION);
00936 glPopMatrix();
00937 glMatrixMode( GL_TEXTURE );
00938 glPopMatrix();
00939 glMatrixMode( GL_MODELVIEW );
00940 glPopMatrix();
00941 }
00942
00943 void Landscape::drawGraphicalReflectionMap()
00944 {
00945 GLState state(GLState::TEXTURE_ON);
00946
00947 glColor3f( 1.f, 1.f, 1.f );
00948 glMatrixMode(GL_PROJECTION);
00949 glPushMatrix();
00950 glLoadIdentity();
00951 gluOrtho2D(0, 800, 0, 600);
00952 glMatrixMode(GL_TEXTURE);
00953 glPushMatrix();
00954 glLoadIdentity();
00955 glMatrixMode(GL_MODELVIEW);
00956 glPushMatrix();
00957 glLoadIdentity();
00958 water_->getReflectionTexture().draw(true);
00959 glBegin(GL_QUADS);
00960 glTexCoord2f(0.f, 0.f);
00961 glVertex2i (0, 0);
00962 glTexCoord2f(1.f, 0.f);
00963 glVertex2i (300, 0);
00964 glTexCoord2f(1.f, 1.f);
00965 glVertex2i (300, 300);
00966 glTexCoord2f(0.f, 1.f);
00967 glVertex2i (0, 300);
00968 glEnd();
00969 glMatrixMode(GL_PROJECTION);
00970 glPopMatrix();
00971 glMatrixMode( GL_TEXTURE );
00972 glPopMatrix();
00973 glMatrixMode( GL_MODELVIEW );
00974 glPopMatrix();
00975 }
00976
00977 void Landscape::updatePlanATexture()
00978 {
00979 ImageModifier::removeWaterFromBitmap(
00980 ScorchedClient::instance()->getLandscapeMaps().getGroundMaps().getHeightMap(),
00981 bitmapPlan_, bitmapPlanAlpha_, bitmapPlanAlphaAlpha_,
00982 (water_->getWaterOn()?water_->getWaterHeight():-50.0f));
00983 DIALOG_ASSERT(planAlphaTexture_.replace(bitmapPlanAlpha_, false));
00984 planAlphaTexture_.draw();
00985 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);
00986 glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);
00987 }
00988
00989 void Landscape::restoreLandscapeTexture()
00990 {
00991 if (textureType_ == eDefault) return;
00992
00993 DIALOG_ASSERT(texture_.replace(mainMap_, false));
00994 textureType_ = eDefault;
00995 }
00996
00997 void Landscape::savePlan()
00998 {
00999 static unsigned counter = 0;
01000 time_t currentTime = time(0);
01001 bitmapPlan_.writeToFile(
01002 S3D::getHomeFile(
01003 S3D::formatStringBuffer("PlanShot-%i-%i.bmp", currentTime, counter++)));
01004 }
01005
01006 Landscape::CameraContext::CameraContext()
01007 {
01008 shadowMap_ = new ShadowMap();
01009 }
01010
01011 ShadowMap &Landscape::getShadowMap()
01012 {
01013 if (GLCamera::getCurrentCamera() ==
01014 &MainCamera::instance()->getCamera())
01015 {
01016 return *cameraContexts_[0].shadowMap_;
01017 }
01018 else
01019 {
01020 return *cameraContexts_[1].shadowMap_;
01021 }
01022 }
01023