p_graphics.cc
Go to the documentation of this file.
00001 /*
00002  *  Stage
00003  *  Copyright (C) Richard Vaughan
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018  *
00019  */
00020 
00021 /*
00022  * Desc: A plugin driver for Player that gives access to Stage devices.
00023  * Author: Richard Vaughan
00024  * Date: 10 December 2004
00025  * CVS: $Id$
00026  */
00027 
00028 // DOCUMENTATION ------------------------------------------------------------
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);// tiny Z offset raises rect above grid
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()) // Display list not created yet
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                 // delay creation of display list so we don't get race conditions on internal subscriptions.
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; //ok
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; //ok
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 }


stage
Author(s): Richard Vaughan , Brian Gerkey , Reed Hedges , Andrew Howard , Toby Collett , Pooya Karimian , Jeremy Asher , Alex Couture-Beil , Geoff Biggs , Rich Mattes , Abbas Sadat
autogenerated on Thu Aug 27 2015 15:20:57