RenderTargets.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 <tankgraph/RenderTargets.h>
00022 #include <tankgraph/TargetRendererImplTank.h>
00023 #include <tankgraph/TargetRendererImplTarget.h>
00024 #include <tankgraph/RenderTracer.h>
00025 #include <tankgraph/RenderGeoms.h>
00026 #include <graph/OptionsDisplay.h>
00027 #include <graph/ModelRendererTree.h>
00028 #include <tank/TankContainer.h>
00029 #include <target/TargetState.h>
00030 #include <client/ScorchedClient.h>
00031 #include <common/OptionsScorched.h>
00032 #include <engine/ActionController.h>
00033 #include <GLEXT/GLGlobalState.h>
00034 #include <landscape/Landscape.h>
00035 #include <land/VisibilityPatchGrid.h>
00036 #include <sky/Sky.h>
00037 #include <algorithm>
00038 
00039 RenderTargets *RenderTargets::instance_ = 0;
00040 
00041 RenderTargets *RenderTargets::instance()
00042 {
00043         if (!instance_)
00044         {
00045                 instance_ = new RenderTargets;
00046         }
00047         return instance_;
00048 }
00049 
00050 RenderTargets::RenderTargets() :
00051         treesDrawn_(0), targetsDrawn_(0)
00052 {
00053 }
00054 
00055 RenderTargets::~RenderTargets()
00056 {
00057 }
00058 
00059 void RenderTargets::Renderer2D::draw(const unsigned state)
00060 {
00061         RenderTargets::instance()->draw2d();
00062 }
00063 
00064 void RenderTargets::Renderer2D::simulate(const unsigned state, float simTime)
00065 {
00066         // Simulate the HUD
00067         TargetRendererImplTankHUD::simulate(simTime);
00068         TargetRendererImplTankAIM::simulate(simTime);
00069 }
00070 
00071 void RenderTargets::Renderer3D::draw(const unsigned state)
00072 {
00073         RenderTracer::instance()->draw(state);
00074         RenderGeoms::instance()->draw(state);
00075         RenderTargets::instance()->draw();
00076 }
00077 
00078 void RenderTargets::Renderer3D::simulate(const unsigned state, float simTime)
00079 {
00080         VisibilityPatchInfo &patchInfo = VisibilityPatchGrid::instance()->getPatchInfo();
00081         stepTime += simTime;
00082 
00083         // step size = 1.0 / physics fps = steps per second
00084         const float stepSize = 1.0f / float(ScorchedClient::instance()->getOptionsGame().getPhysicsFPS());
00085         if (stepTime >= stepSize)
00086         {
00087                 float time = stepTime * ScorchedClient::instance()->getActionController().getFast().asFloat();
00088 
00089                 void *currentPatchPtr = 0, *currentObject = 0;
00090                 TargetListIterator patchItor(patchInfo.getTargetVisibility());
00091                 TargetVisibilityIterator itor;
00092                 while (currentPatchPtr = patchItor.getNext())
00093                 {
00094                         TargetVisibilityPatch *currentPatch = (TargetVisibilityPatch *) currentPatchPtr;
00095 
00096                         itor.init(currentPatch->getTargets());
00097                         while (currentObject = itor.getNext())
00098                         {
00099                                 Target *target = (Target *) currentObject;
00100                                 TargetRendererImpl *renderImpl = (TargetRendererImpl *) target->getRenderer();
00101                                 renderImpl->simulate(time);
00102                         }
00103                 }
00104 
00105                 itor.init(TargetVisibilityPatch::getLargeTargets());
00106                 while (currentObject = itor.getNext())
00107                 {
00108                         Target *target = (Target *) currentObject;
00109                         TargetRendererImpl *renderImpl = (TargetRendererImpl *) target->getRenderer();
00110                         renderImpl->simulate(time);
00111                 }
00112 
00113                 stepTime = 0.0f;
00114         }
00115 }
00116 
00117 void RenderTargets::Renderer3D::enterState(const unsigned state)
00118 {
00119 
00120 }
00121 
00122 static void drawTargetShadows(TargetVisibilityIterator &itor, float distance) 
00123 {
00124         void *currentObject = 0;
00125         while (currentObject = itor.getNext())
00126         {
00127                 Target *target = (Target *) currentObject;
00128                 if (target->getTargetState().getDisplayHardwareShadow())
00129                 {
00130                         if (target->isTarget())
00131                         {
00132                                 TargetRendererImplTarget *renderImpl = (TargetRendererImplTarget *) target->getRenderer();
00133                                 renderImpl->renderShadow(distance);
00134                         }
00135                         else
00136                         {
00137                                 TargetRendererImplTank *renderImpl = (TargetRendererImplTank *) target->getRenderer();
00138                                 renderImpl->renderShadow(distance);
00139                         }
00140                 }
00141         }
00142 }
00143 
00144 void RenderTargets::shadowDraw()
00145 {
00146         VisibilityPatchInfo &patchInfo = VisibilityPatchGrid::instance()->getPatchInfo();
00147 
00148         GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "LANDSCAPE_SHADOWS_DRAW_OBJ");
00149         {
00150                 unsigned int wantedstate = GLState::BLEND_OFF | 
00151                         GLState::ALPHATEST_OFF | GLState::TEXTURE_OFF;
00152                 GLState glstate(wantedstate);
00153 
00154                 {
00155                         GLGlobalState globalState(0);
00156                         ModelRendererTree::setSkipPre(true);
00157                         ModelRendererTree::drawInternalPre(false);
00158 
00159                         void *currentPatchPtr = 0;
00160                         TargetListIterator patchItor(patchInfo.getTreeVisibility());
00161                         TargetVisibilityIterator itor;
00162                         while (currentPatchPtr = patchItor.getNext())
00163                         {
00164                                 TargetVisibilityPatch *currentPatch = (TargetVisibilityPatch *) currentPatchPtr;
00165 
00166                                 itor.init(currentPatch->getTrees());
00167                                 drawTargetShadows(itor, currentPatch->getDistance());
00168                         }
00169 
00170                         ModelRendererTree::setSkipPre(false);
00171                 }
00172                 {
00173                         GLGlobalState globalState(0);
00174                         void *currentPatchPtr = 0;
00175                         TargetListIterator patchItor(patchInfo.getTargetVisibility());
00176                         TargetVisibilityIterator itor;
00177                         while (currentPatchPtr = patchItor.getNext())
00178                         {
00179                                 TargetVisibilityPatch *currentPatch = (TargetVisibilityPatch *) currentPatchPtr;
00180 
00181                                 itor.init(currentPatch->getTargets());
00182                                 drawTargetShadows(itor, currentPatch->getDistance());
00183                         }
00184                 }
00185 
00186                 {
00187                         GLGlobalState globalState(0);
00188                         TargetVisibilityIterator itor;
00189 
00190                         itor.init(TargetVisibilityPatch::getLargeTargets());
00191                         drawTargetShadows(itor, 0.0f);
00192                 }
00193         }
00194         GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "LANDSCAPE_SHADOWS_DRAW_OBJ");
00195 }
00196 
00197 static void drawTargets(TargetVisibilityIterator &itor, float distance)
00198 {
00199         void *currentObject = 0;
00200         while (currentObject = itor.getNext())
00201         {
00202                 Target *target = (Target *) currentObject;
00203                 if (target->isTarget())
00204                 {
00205                         TargetRendererImplTarget *renderImpl = (TargetRendererImplTarget *) target->getRenderer();
00206                         renderImpl->render(distance);
00207                 }
00208                 else
00209                 {
00210                         TargetRendererImplTank *renderImpl = (TargetRendererImplTank *) target->getRenderer();
00211                         renderImpl->render(distance);
00212                 }
00213         }
00214 }
00215 
00216 void RenderTargets::draw()
00217 {
00218         // Don't put fully transparent areas into the depth buffer
00219         unsigned int wantedstate = GLState::BLEND_ON | 
00220                 GLState::ALPHATEST_ON | GLState::TEXTURE_ON | 
00221                 GLState::NORMALIZE_ON | GLState::LIGHTING_ON | 
00222                 GLState::LIGHT1_ON;
00223         GLState glstate(wantedstate);
00224         Landscape::instance()->getSky().getSun().setLightPosition(false);
00225 
00226         VisibilityPatchInfo &patchInfo = VisibilityPatchGrid::instance()->getPatchInfo();
00227 
00228         // Trees
00229         treesDrawn_ = 0;
00230         GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "TARGETS_DRAW_TREES");
00231         if (!OptionsDisplay::instance()->getNoTrees())
00232         {
00233                 GLGlobalState globalState(0);
00234                 ModelRendererTree::setSkipPre(true);
00235                 ModelRendererTree::drawInternalPre(true);
00236 
00237                 void *currentPatchPtr = 0;
00238                 TargetListIterator patchItor(patchInfo.getTreeVisibility());
00239                 TargetVisibilityIterator itor;
00240                 while (currentPatchPtr = patchItor.getNext())
00241                 {
00242                         TargetVisibilityPatch *currentPatch = (TargetVisibilityPatch *) currentPatchPtr;
00243 
00244                         itor.init(currentPatch->getTrees());
00245                         drawTargets(itor, currentPatch->getDistance());
00246 
00247                         treesDrawn_+=currentPatch->getTrees().size();
00248                 }
00249 
00250                 ModelRendererTree::setSkipPre(false);
00251         }
00252         GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "TARGETS_DRAW_TREES");
00253 
00254         // Models
00255         targetsDrawn_ = 0;
00256         GAMESTATE_PERF_COUNTER_START(ScorchedClient::instance()->getGameState(), "TARGETS_DRAW_MODELS");
00257         {
00258                 GLGlobalState globalState(0);
00259 
00260                 void *currentPatchPtr = 0, *currentObject = 0;
00261                 TargetListIterator patchItor(patchInfo.getTargetVisibility());
00262                 TargetVisibilityIterator itor;
00263                 while (currentPatchPtr = patchItor.getNext())
00264                 {
00265                         TargetVisibilityPatch *currentPatch = (TargetVisibilityPatch *) currentPatchPtr;
00266 
00267                         itor.init(currentPatch->getTargets());
00268                         drawTargets(itor, currentPatch->getDistance());
00269 
00270                         targetsDrawn_+=currentPatch->getTargets().size();
00271                 }
00272 
00273                 {
00274                         itor.init(TargetVisibilityPatch::getLargeTargets());
00275                         drawTargets(itor, 0.0f);
00276 
00277                         targetsDrawn_+=TargetVisibilityPatch::getLargeTargets().size();
00278                 }
00279         }
00280         GAMESTATE_PERF_COUNTER_END(ScorchedClient::instance()->getGameState(), "TARGETS_DRAW_MODELS");
00281 }
00282 
00283 static void drawTargets2D(TargetVisibilityIterator &itor, float distance)
00284 {
00285         void *currentObject = 0;
00286         while (currentObject = itor.getNext())
00287         {
00288                 Target *target = (Target *) currentObject;
00289                 if (target->isTarget())
00290                 {
00291                         TargetRendererImplTarget *renderImpl = (TargetRendererImplTarget *) target->getRenderer();
00292                         renderImpl->render2D(distance);
00293                 }
00294                 else
00295                 {
00296                         TargetRendererImplTank *renderImpl = (TargetRendererImplTank *) target->getRenderer();
00297                         renderImpl->render2D(distance);
00298                 }
00299         }
00300 }
00301 
00302 void RenderTargets::draw2d()
00303 {
00304         VisibilityPatchInfo &patchInfo = VisibilityPatchGrid::instance()->getPatchInfo();
00305 
00306         // 2D
00307         {
00308                 void *currentPatchPtr = 0;
00309                 TargetListIterator patchItor(patchInfo.getTargetVisibility());
00310                 TargetVisibilityIterator itor;
00311                 while (currentPatchPtr = patchItor.getNext())
00312                 {
00313                         TargetVisibilityPatch *currentPatch = (TargetVisibilityPatch *) currentPatchPtr;
00314 
00315                         itor.init(currentPatch->getTooltips());
00316                         drawTargets2D(itor, currentPatch->getDistance());
00317                 }
00318         }
00319 }

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