00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
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
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
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
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
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
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
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 }