Landscape.cpp

Go to the documentation of this file.
00001 ////////////////////////////////////////////////////////////////////////////////
00002 //    Scorched3D (c) 2000-2009
00003 //
00004 //    This file is part of Scorched3D.
00005 //
00006 //    Scorched3D is free software; you can redistribute it and/or modify
00007 //    it under the terms of the GNU General Public License as published by
00008 //    the Free Software Foundation; either version 2 of the License, or
00009 //    (at your option) any later version.
00010 //
00011 //    Scorched3D is distributed in the hope that it will be useful,
00012 //    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013 //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014 //    GNU General Public License for more details.
00015 //
00016 //    You should have received a copy of the GNU General Public License
00017 //    along with Scorched3D; if not, write to the Free Software
00018 //    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
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                         // Update the plan texture
00097                         updatePlanATexture();
00098                         updatePlanTexture();
00099 
00100                         // Update the landscape
00101                         GraphicalLandscapeMap *landscapeMap = (GraphicalLandscapeMap *)
00102                                 ScorchedClient::instance()->getLandscapeMaps().
00103                                         getGroundMaps().getHeightMap().getGraphicalMap();
00104                         landscapeMap->updateWholeBuffer();
00105 
00106                         // Re-calculate the landsacpe on the wind indicator
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; // Recalculate the water in x seconds
00126         }
00127 }
00128 
00129 void Landscape::reset(ProgressCounter *counter)
00130 {
00131         changeCount_++;
00132 
00133         // Recalculate all landscape objects
00134         // Ensure all objects use any new landscape
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         // Turn off texturing
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         // Get the sun's position and landscape dimensions
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         // Bind the frame buffer so we can render into it
00168         shadowFrameBuffer_.bind();
00169         glViewport(0, 0, shadowFrameBuffer_.getWidth(), shadowFrameBuffer_.getHeight());
00170 
00171         // Setup the view from the sun
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         // Save the matrixs used for the sun
00185         glGetFloatv(GL_MODELVIEW_MATRIX, lightModelMatrix_);
00186         glGetFloatv(GL_PROJECTION_MATRIX, lightProjMatrix_);
00187 
00188         // Clear and setup the offset
00189     glClear(GL_DEPTH_BUFFER_BIT);
00190 
00191         // Set poly offset so that the shadows dont get precision artifacts
00192     glPolygonOffset(10.0f, 10.0f);
00193     glEnable(GL_POLYGON_OFFSET_FILL);
00194 
00195         //Disable color writes, and use flat shading for speed
00196     glColorMask(0, 0, 0, 0); 
00197 
00198         // Draw items that cast shadows
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                                         //*src = 0.0f; // Black and white
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         //restore states
00258     glColorMask(1, 1, 1, 1); 
00259 
00260         // Reset offset
00261         glDisable(GL_POLYGON_OFFSET_FILL);
00262 
00263         // Stop drawing to frame buffer
00264         shadowFrameBuffer_.unBind();
00265 
00266         // Reset camera
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         // NOTE: The following code is drawn with fog on
00278         // Be carefull as this we "dull" bilboard textures
00279         if (!OptionsDisplay::instance()->getNoFog())
00280         {
00281                 glEnable(GL_FOG); // NOTE: Fog on
00282         }
00283 }
00284 
00285 void Landscape::drawTearDown()
00286 {
00287         glDisable(GL_FOG); // NOTE: Fog off
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                 // flip geometry at z=0 plane
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                 //water_->drawPoints(); // Bad reflections in large wind
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         // Choose the correct sizes for the current LOD
00440         int mapTexSize = getMapTexSize();
00441         int planTexSize = getPlanTexSize();
00442 
00443         // Generate the texture used to map onto the landscape
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                         // Create the frame buffer
00464                         if (!shadowFrameBuffer_.create(2048, 2048))
00465                         {
00466                                 S3D::dialogExit("Scorched3D", "Failed to create shadow frame buffer");
00467                         }
00468                 }
00469         }
00470 
00471         // Removed for now as plan is square
00472         // If (when) re-instated need to scale alpha map by playable arena, not full map size
00473         /*ImageHandle plana = ImageFactory::loadImageHandle(S3D::getDataFile("data/windows/planaa.bmp"));
00474         ImageModifier::scalePlanBitmap(bitmapPlanAlphaAlpha_, plana,
00475                 ScorchedClient::instance()->getLandscapeMaps().getGroundMaps().getLandscapeWidth(),
00476         ScorchedClient::instance()->getLandscapeMaps().getGroundMaps().getLandscapeHeight());*/
00477 
00478         // Load the texture bitmaps from resources 
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                 // Generate the new landscape
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                 // Generate splat texture maps
00517                 ImageModifier::addTexturesToBitmap(
00518                         splatMap_,
00519                         bitmapRock, bitmapShore, bitmaps, 4);
00520                 splatTextures_.create(splatMap_, false);
00521 
00522                 // Set up the splat textures
00523                 splatMaskTexture1_.replace(splatMask1, false);
00524                 splatMaskTexture2_.replace(splatMask2, false);
00525                 splatMaskTextureBorder1_.replace(splatMaskBorder1, false);
00526                 splatMaskTextureBorder2_.replace(splatMaskBorder2, false);
00527 #endif
00528 
00529                 // Set the general surround and roof texture
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         // Add lighting to the landscape texture
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,  // Match with shadows
00550                         tex->skyambience, tex->skydiffuse, counter);
00551         }
00552         else
00553         {
00554                 // Load shader
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         // Add shadows to the mainmap
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         // Create the main landscape texture
00582         DIALOG_ASSERT(texture_.replace(mainMap_, false));
00583 
00584     // Create the landscape texture used for the small plan window
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         // Generate the scorch map for the landscape
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         // Arena
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         // Magma
00616         ImageHandle bitmapMagma = 
00617                 ImageFactory::loadImageHandle(S3D::getDataFile(tex->magmasmall.c_str()));
00618         DIALOG_ASSERT(magTexture_.replace(bitmapMagma));
00619 
00620         // Detail
00621         ImageHandle bitmapDetail = 
00622                 ImageFactory::loadImageHandle(S3D::getDataFile(tex->detail.c_str()));
00623         DIALOG_ASSERT(detailTexture_.replace(bitmapDetail, true));
00624 
00625         // Set the fog color
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         // Load the sky
00636         sky_->generate();
00637 
00638         // Load water
00639         water_->generate(counter);
00640 
00641         // Create the plan textures (for the plan and wind dialogs)
00642         updatePlanTexture();
00643         updatePlanATexture();
00644 
00645         // Add any ambientsounds
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         // Create texture matrix
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         // Copy and transpose
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         // Apply the inverse transformation
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         // Create and save texture matrix
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         // Draw Land
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         // Draw Surround
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                         // Disable Tex
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         // Disable Tex
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 

Generated on Mon Feb 16 15:14:47 2009 for Scorched3D by  doxygen 1.5.3