00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00049 #include "p_driver.h"
00050
00051 #include <iostream>
00052 using namespace std;
00053
00054 #ifdef G_OS_WIN32
00055 #define WIN32_LEAN_AND_MEAN 1
00056 #include <windows.h>
00057 #endif
00058
00059 struct clientDisplaylist {
00060 int DisplayList;
00061 vector<Message> RenderItems;
00062 };
00063
00064 class PlayerGraphicsVis: public Stg::Visualizer {
00065 private:
00066
00067 public:
00068 PlayerGraphicsVis() :
00069 Stg::Visualizer("Graphics", "custom_vis") {
00070 }
00071 ;
00072 virtual ~PlayerGraphicsVis(void) {
00073 for (queuemap::iterator itr = ClientDisplayLists.begin(); itr
00074 != ClientDisplayLists.end(); ++itr)
00075 RemoveDisplayList(itr->second);
00076 }
00077 ;
00078 virtual void Visualize(Stg::Model* mod, Stg::Camera* cam) {
00079 GLint OldDepthFunc;
00080 glGetIntegerv(GL_DEPTH_FUNC, &OldDepthFunc);
00081 glDepthFunc(GL_LEQUAL);
00082 for (queuemap::iterator itr = ClientDisplayLists.begin(); itr
00083 != ClientDisplayLists.end(); ++itr) {
00084 glPushMatrix();
00085 glTranslatef(0, 0, 0.01);
00086 glCallList(itr->second.DisplayList);
00087 glPopMatrix();
00088 }
00089 glDepthFunc(OldDepthFunc);
00090 }
00091
00092 void Clear(MessageQueue * client) {
00093 struct clientDisplaylist &list = GetDisplayList(client);
00094 list.RenderItems.clear();
00095 glNewList(list.DisplayList, GL_COMPILE );
00096 glEndList();
00097 }
00098 ;
00099
00100 bool HasActiveDisplayList(MessageQueue * client) {
00101 queuemap::iterator found = ClientDisplayLists.find(client);
00102 if (found == ClientDisplayLists.end())
00103 return false;
00104 else if (found->second.DisplayList == -1)
00105 return false;
00106 return true;
00107 }
00108
00109 struct clientDisplaylist & GetDisplayList(MessageQueue * client) {
00110 queuemap::iterator found = ClientDisplayLists.find(client);
00111 if (found == ClientDisplayLists.end())
00112 {
00113 clientDisplaylist & clientDisp = ClientDisplayLists[client];
00114 clientDisp.DisplayList = glGenLists(1);
00115 return clientDisp;
00116 }
00117 else if (found->second.DisplayList == -1)
00118 found->second.DisplayList = glGenLists(1);
00119 return found->second;
00120 }
00121
00122 void BuildDisplayList(MessageQueue * client) {
00123 struct clientDisplaylist &list = GetDisplayList(client);
00124 glNewList(list.DisplayList, GL_COMPILE );
00125 glPushMatrix();
00126 for (vector<Message>::iterator itr = list.RenderItems.begin(); itr
00127 != list.RenderItems.end(); ++itr)
00128 RenderItem(*itr);
00129 glPopMatrix();
00130 glEndList();
00131 }
00132
00133 void RemoveDisplayList(struct clientDisplaylist & list) {
00134 if (list.DisplayList > 0)
00135 glDeleteLists(list.DisplayList, 1);
00136 }
00137
00138 virtual void AppendItem(MessageQueue * client, Message & item) {
00139 struct clientDisplaylist & list = GetDisplayList(client);
00140 list.RenderItems.push_back(item);
00141 }
00142 ;
00143
00144 void Subscribe(QueuePointer &queue) {
00145 if (queue == NULL)
00146 return;
00147 clientDisplaylist & clientDisp = ClientDisplayLists[queue.get()];
00148
00149 clientDisp.DisplayList = -1;
00150 }
00151
00152 void Unsubscribe(QueuePointer &queue) {
00153 if (queue == NULL)
00154 return;
00155 if (HasActiveDisplayList(queue.get()))
00156 {
00157 struct clientDisplaylist & list = GetDisplayList(queue.get());
00158 RemoveDisplayList(list);
00159 }
00160 ClientDisplayLists.erase(queue.get());
00161 }
00162
00163 void glPlayerColour(const player_color_t & colour) {
00164 glColor4f(static_cast<float> (colour.red) / 255.0,
00165 static_cast<float> (colour.green) / 255.0,
00166 static_cast<float> (colour.blue) / 255.0, 1
00167 - static_cast<float> (colour.alpha) / 255.0);
00168 }
00169
00170 virtual void RenderItem(Message & item) = 0;
00171
00172 private:
00173 typedef map<MessageQueue *, struct clientDisplaylist> queuemap;
00174 queuemap ClientDisplayLists;
00175 };
00176
00177 class PlayerGraphics2dVis: public PlayerGraphicsVis {
00178 public:
00179 PlayerGraphics2dVis() :
00180 PlayerGraphicsVis() {
00181 }
00182 ;
00183 ~PlayerGraphics2dVis() {
00184 }
00185 ;
00186
00187 void RenderItem(Message & item);
00188 };
00189
00190 class PlayerGraphics3dVis: public PlayerGraphicsVis {
00191 public:
00192 PlayerGraphics3dVis() :
00193 PlayerGraphicsVis() {
00194 }
00195 ;
00196 ~PlayerGraphics3dVis() {
00197 }
00198 ;
00199
00200 void RenderItem(Message & item);
00201 };
00202
00203 InterfaceGraphics2d::InterfaceGraphics2d(player_devaddr_t addr,
00204 StgDriver* driver, ConfigFile* cf, int section) :
00205 InterfaceModel(addr, driver, cf, section, "") {
00206 vis = new PlayerGraphics2dVis;
00207 mod->AddVisualizer( vis, true );
00208 }
00209
00210 InterfaceGraphics2d::~InterfaceGraphics2d() {
00211 mod->RemoveVisualizer(vis);
00212 delete vis;
00213 }
00214
00215 void InterfaceGraphics2d::Subscribe(QueuePointer &queue) {
00216 vis->Subscribe(queue);
00217 }
00218
00219 void InterfaceGraphics2d::Unsubscribe(QueuePointer &queue) {
00220 vis->Unsubscribe(queue);
00221 }
00222
00223 int InterfaceGraphics2d::ProcessMessage(QueuePointer & resp_queue,
00224 player_msghdr_t* hdr, void* data) {
00225 if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
00226 PLAYER_GRAPHICS2D_CMD_CLEAR, this->addr)) {
00227 vis->Clear(resp_queue.get());
00228 return 0;
00229 }
00230
00231 if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
00232 PLAYER_GRAPHICS2D_CMD_POINTS, this->addr)
00233 || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
00234 PLAYER_GRAPHICS2D_CMD_POLYLINE, this->addr)
00235 #ifdef PLAYER_GRAPHICS2D_CMD_MULTILINE
00236 || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
00237 PLAYER_GRAPHICS2D_CMD_MULTILINE, this->addr)
00238 #endif
00239 || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
00240 PLAYER_GRAPHICS2D_CMD_POLYGON, this->addr)) {
00241 Message msg(*hdr, data);
00242 vis->AppendItem(resp_queue.get(), msg);
00243 vis->BuildDisplayList(resp_queue.get());
00244 return 0;
00245 }
00246
00247 PLAYER_WARN2("stage graphics2d doesn't support message %d:%d.", hdr->type,
00248 hdr->subtype);
00249 return -1;
00250 }
00251
00252 void PlayerGraphics2dVis::RenderItem(Message & item) {
00253 glDepthMask(GL_FALSE);
00254 int type = item.GetHeader()->subtype;
00255 switch (type) {
00256 case PLAYER_GRAPHICS2D_CMD_POINTS: {
00257 player_graphics2d_cmd_points_t
00258 & data =
00259 *reinterpret_cast<player_graphics2d_cmd_points_t*> (item.GetPayload());
00260 glPlayerColour(data.color);
00261 glBegin(GL_POINTS);
00262 for (unsigned ii = 0; ii < data.points_count; ++ii)
00263 glVertex3f(data.points[ii].px, data.points[ii].py, 0);
00264 glEnd();
00265 }
00266 break;
00267 case PLAYER_GRAPHICS2D_CMD_POLYLINE: {
00268 player_graphics2d_cmd_polyline_t
00269 & data =
00270 *reinterpret_cast<player_graphics2d_cmd_polyline_t*> (item.GetPayload());
00271 glPlayerColour(data.color);
00272 glBegin(GL_LINE_STRIP);
00273 for (unsigned ii = 0; ii < data.points_count; ++ii)
00274 glVertex3f(data.points[ii].px, data.points[ii].py, 0);
00275 glEnd();
00276 }
00277 break;
00278
00279 #ifdef PLAYER_GRAPHICS2D_CMD_MULTILINE
00280 case PLAYER_GRAPHICS2D_CMD_MULTILINE: {
00281 player_graphics2d_cmd_multiline_t
00282 & data =
00283 *reinterpret_cast<player_graphics2d_cmd_multiline_t*> (item.GetPayload());
00284 glPlayerColour(data.color);
00285 glBegin(GL_LINES);
00286 for (unsigned ii = 0; ii < data.points_count; ++ii)
00287 glVertex3f(data.points[ii].px, data.points[ii].py, 0);
00288 glEnd();
00289 }
00290 break;
00291 #endif
00292
00293
00294
00295
00296
00297
00298 case PLAYER_GRAPHICS2D_CMD_POLYGON: {
00299 player_graphics2d_cmd_polygon_t
00300 & data =
00301 *reinterpret_cast<player_graphics2d_cmd_polygon_t*> (item.GetPayload());
00302 if (data.filled) {
00303 glPlayerColour(data.fill_color);
00304 glBegin(GL_POLYGON);
00305 for (unsigned ii = 0; ii < data.points_count; ++ii)
00306 glVertex3f(data.points[ii].px, data.points[ii].py, 0);
00307 glEnd();
00308 }
00309 glPlayerColour(data.color);
00310 glBegin(GL_LINE_LOOP);
00311 for (unsigned ii = 0; ii < data.points_count; ++ii)
00312 glVertex3f(data.points[ii].px, data.points[ii].py, 0);
00313 glEnd();
00314 }
00315 break;
00316 }
00317 glDepthMask(GL_TRUE);
00318
00319 }
00320
00321 InterfaceGraphics3d::InterfaceGraphics3d(player_devaddr_t addr,
00322 StgDriver* driver, ConfigFile* cf, int section) :
00323 InterfaceModel(addr, driver, cf, section, "") {
00324 vis = new PlayerGraphics3dVis;
00325 mod->AddVisualizer( vis, true );
00326 }
00327
00328 InterfaceGraphics3d::~InterfaceGraphics3d() {
00329 mod->RemoveVisualizer(vis);
00330 delete vis;
00331 }
00332
00333 void InterfaceGraphics3d::Subscribe(QueuePointer &queue) {
00334 vis->Subscribe(queue);
00335 }
00336
00337 void InterfaceGraphics3d::Unsubscribe(QueuePointer &queue) {
00338 vis->Unsubscribe(queue);
00339 }
00340
00341 int InterfaceGraphics3d::ProcessMessage(QueuePointer & resp_queue,
00342 player_msghdr_t* hdr, void* data) {
00343 if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
00344 PLAYER_GRAPHICS3D_CMD_CLEAR, this->addr)) {
00345 vis->Clear(resp_queue.get());
00346 return 0;
00347 }
00348
00349 if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
00350 PLAYER_GRAPHICS3D_CMD_PUSH, this->addr) || Message::MatchMessage(
00351 hdr, PLAYER_MSGTYPE_CMD, PLAYER_GRAPHICS3D_CMD_POP, this->addr)
00352 || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
00353 PLAYER_GRAPHICS3D_CMD_DRAW, this->addr)
00354 || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
00355 PLAYER_GRAPHICS3D_CMD_TRANSLATE, this->addr)
00356 || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
00357 PLAYER_GRAPHICS3D_CMD_ROTATE, this->addr)) {
00358 Message msg(*hdr, data);
00359 vis->AppendItem(resp_queue.get(), msg);
00360 vis->BuildDisplayList(resp_queue.get());
00361 return 0;
00362 }
00363
00364 PLAYER_WARN2("stage graphics2d doesn't support message %d:%d.", hdr->type,
00365 hdr->subtype);
00366 return -1;
00367 }
00368
00369 void PlayerGraphics3dVis::RenderItem(Message & item) {
00370 int type = item.GetHeader()->subtype;
00371 switch (type) {
00372 case PLAYER_GRAPHICS3D_CMD_DRAW: {
00373 player_graphics3d_cmd_draw_t
00374 & data =
00375 *reinterpret_cast<player_graphics3d_cmd_draw_t*> (item.GetPayload());
00376 glPlayerColour(data.color);
00377 switch (data.draw_mode) {
00378 case PLAYER_DRAW_POINTS:
00379 glBegin(GL_POINTS);
00380 break;
00381 case PLAYER_DRAW_LINES:
00382 glBegin(GL_LINES);
00383 break;
00384 case PLAYER_DRAW_LINE_STRIP:
00385 glBegin(GL_LINE_STRIP);
00386 break;
00387 case PLAYER_DRAW_LINE_LOOP:
00388 glBegin(GL_LINE_LOOP);
00389 break;
00390 case PLAYER_DRAW_TRIANGLES:
00391 glBegin(GL_TRIANGLES);
00392 break;
00393 case PLAYER_DRAW_TRIANGLE_STRIP:
00394 glBegin(GL_TRIANGLE_STRIP);
00395 break;
00396 case PLAYER_DRAW_TRIANGLE_FAN:
00397 glBegin(GL_TRIANGLE_FAN);
00398 break;
00399 case PLAYER_DRAW_QUADS:
00400 glBegin(GL_QUADS);
00401 break;
00402 case PLAYER_DRAW_QUAD_STRIP:
00403 glBegin(GL_QUAD_STRIP);
00404 break;
00405 case PLAYER_DRAW_POLYGON:
00406 glBegin(GL_POLYGON);
00407 break;
00408 default:
00409 fprintf(stderr,"Unknown graphics 3d draw mode\n");
00410 return;
00411 }
00412 for (unsigned ii = 0; ii < data.points_count; ++ii)
00413 glVertex3f(data.points[ii].px, data.points[ii].py,
00414 data.points[ii].pz);
00415 glEnd();
00416 }
00417 break;
00418 case PLAYER_GRAPHICS3D_CMD_TRANSLATE: {
00419 player_graphics3d_cmd_translate_t
00420 & data =
00421 *reinterpret_cast<player_graphics3d_cmd_translate_t*> (item.GetPayload());
00422 glTranslatef(data.x, data.y, data.z);
00423 }
00424 break;
00425 case PLAYER_GRAPHICS3D_CMD_ROTATE: {
00426 player_graphics3d_cmd_rotate_t
00427 & data =
00428 *reinterpret_cast<player_graphics3d_cmd_rotate_t*> (item.GetPayload());
00429 glRotatef(data.a, data.x, data.y, data.z);
00430 }
00431 break;
00432 case PLAYER_GRAPHICS3D_CMD_PUSH: {
00433 glPushMatrix();
00434 }
00435 break;
00436 case PLAYER_GRAPHICS3D_CMD_POP: {
00437 glPopMatrix();
00438 }
00439 break;
00440 }
00441 }