00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include <tankgraph/RenderTracer.h>
00022 #include <tank/TankContainer.h>
00023 #include <GLEXT/GLTexture.h>
00024 #include <image/ImageBitmap.h>
00025 #include <client/ScorchedClient.h>
00026
00027 RenderTracer *RenderTracer::instance_ = 0;
00028
00029 RenderTracer *RenderTracer::instance()
00030 {
00031 if (!instance_) instance_ = new RenderTracer;
00032 return instance_;
00033 }
00034
00035 RenderTracer::RenderTracer() :
00036 GameStateI("RenderTracer"),
00037 current_(0), listNo_(0)
00038 {
00039 obj_ = gluNewQuadric();
00040 }
00041
00042 RenderTracer::~RenderTracer()
00043 {
00044 gluDeleteQuadric(obj_);
00045 }
00046
00047 void RenderTracer::clearTracers()
00048 {
00049 if (current_)
00050 {
00051 current_->lines.clear();
00052 current_->points.clear();
00053 }
00054 }
00055
00056 void RenderTracer::clearTracerLines()
00057 {
00058 if (current_)
00059 {
00060 current_->lines.clear();
00061 }
00062 }
00063
00064 void RenderTracer::draw(const unsigned state)
00065 {
00066 Tank *current = ScorchedClient::instance()->getTankContainer().getCurrentTank();
00067 if (!current) return;
00068
00069 if (!current_ ||
00070 current_->tank != current->getPlayerId())
00071 {
00072 std::map<unsigned int, TraceEntry>::iterator itor =
00073 traceEntries_.find(current->getPlayerId());
00074 if (itor == traceEntries_.end())
00075 {
00076 TraceEntry entry(current->getPlayerId());
00077 traceEntries_[current->getPlayerId()] = entry;
00078 current_ = &traceEntries_[current->getPlayerId()];
00079 }
00080 else
00081 {
00082 current_ = &(*itor).second;
00083 }
00084 }
00085 if (current_->points.empty()) return;
00086
00087 glColor3fv(current->getColor());
00088
00089 std::list<Vector>::iterator itor = current_->points.begin();
00090 std::list<Vector>::iterator itorend = current_->points.end();
00091 for (;itor != itorend; itor++)
00092 {
00093 drawTracerEnd(*itor);
00094 }
00095
00096 std::list<std::list<TracerLinePoint> >::iterator itor2 = current_->lines.begin();
00097 std::list<std::list<TracerLinePoint> >::iterator itorend2 = current_->lines.end();
00098 for (;itor2 != itorend2; itor2++)
00099 {
00100 drawSmokeTracer(*itor2);
00101 }
00102 }
00103
00104 void RenderTracer::drawTracerEnd(Vector &position)
00105 {
00106 GLState currentState(GLState::TEXTURE_OFF | GLState::BLEND_OFF);
00107
00108 glPushMatrix();
00109 glTranslatef(position[0], position[1], position[2]);
00110 if (!listNo_)
00111 {
00112 glNewList(listNo_ = glGenLists(1), GL_COMPILE_AND_EXECUTE);
00113 gluSphere(obj_, 0.5f, 4, 2);
00114 glEndList();
00115 }
00116 else
00117 {
00118 glCallList(listNo_);
00119 }
00120 glPopMatrix();
00121 }
00122
00123 void RenderTracer::drawSmokeTracer(std::list<TracerLinePoint> &positions)
00124 {
00125 GLState currentState(GLState::TEXTURE_OFF | GLState::BLEND_OFF);
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139 for (int i=0; i<2; i++)
00140 {
00141 glBegin(GL_QUAD_STRIP);
00142 Vector lastPos;
00143 float totalDist = 0.0f;
00144 std::list<TracerLinePoint>::iterator itor = positions.begin();
00145 std::list<TracerLinePoint>::iterator itorend = positions.end();
00146 for (;itor != itorend; itor++)
00147 {
00148 Vector ¤tPos = (*itor).position;
00149 Vector &cross = (*itor).cross;
00150 if (itor == positions.begin()) lastPos = currentPos;
00151
00152 float dist = (lastPos - currentPos).Magnitude();
00153 if (dist < 100.0f)
00154 {
00155 if (i==0)
00156 {
00157 glTexCoord2f(0.0f, totalDist);
00158 glVertex3fv(currentPos - cross / 2.0f);
00159 glTexCoord2f(1.0f, totalDist);
00160 glVertex3fv(currentPos + cross / 2.0f);
00161 }
00162 else
00163 {
00164 glTexCoord2f(0.0f, totalDist);
00165 glVertex3fv(currentPos + cross / 2.0f);
00166 glTexCoord2f(1.0f, totalDist);
00167 glVertex3fv(currentPos - cross / 2.0f);
00168 }
00169 }
00170 else
00171 {
00172 glEnd();
00173 glBegin(GL_QUAD_STRIP);
00174 }
00175
00176 totalDist += dist / 10.0f;
00177 lastPos = currentPos;
00178 }
00179 glEnd();
00180 }
00181
00182 }
00183
00184 void RenderTracer::newGame()
00185 {
00186 traceEntries_.clear();
00187 current_ = 0;
00188 }
00189
00190 void RenderTracer::addTracer(unsigned int tank, Vector &position)
00191 {
00192 std::map<unsigned int, TraceEntry>::iterator itor =
00193 traceEntries_.find(tank);
00194 if (itor == traceEntries_.end())
00195 {
00196 TraceEntry entry(tank);
00197 entry.points.push_back(position);
00198 traceEntries_[tank] = entry;
00199 }
00200 else
00201 {
00202 (*itor).second.points.push_back(position);
00203 }
00204 }
00205
00206 void RenderTracer::addSmokeTracer(unsigned int tank,
00207 Vector &position, std::list<TracerLinePoint> &positions)
00208 {
00209 std::map<unsigned int, TraceEntry>::iterator itor =
00210 traceEntries_.find(tank);
00211 if (itor == traceEntries_.end())
00212 {
00213 TraceEntry entry(tank);
00214 entry.lines.push_back(positions);
00215 entry.points.push_back(position);
00216 traceEntries_[tank] = entry;
00217 }
00218 else
00219 {
00220 (*itor).second.lines.push_back(positions);
00221 (*itor).second.points.push_back(position);
00222 }
00223 }