p_graphics.cc
Go to the documentation of this file.
1 /*
2  * Stage
3  * Copyright (C) Richard Vaughan
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *
19  */
20 
21 /*
22  * Desc: A plugin driver for Player that gives access to Stage devices.
23  * Author: Richard Vaughan
24  * Date: 10 December 2004
25  * CVS: $Id$
26  */
27 
28 // DOCUMENTATION ------------------------------------------------------------
29 
49 #include "p_driver.h"
50 
51 #include <iostream>
52 using namespace std;
53 
54 #ifdef G_OS_WIN32
55 #define WIN32_LEAN_AND_MEAN 1
56 #include <windows.h>
57 #endif
58 
61  vector<Message> RenderItems;
62 };
63 
65 private:
66 
67 public:
69  Stg::Visualizer("Graphics", "custom_vis") {
70  }
71  ;
72  virtual ~PlayerGraphicsVis(void) {
73  for (queuemap::iterator itr = ClientDisplayLists.begin(); itr
74  != ClientDisplayLists.end(); ++itr)
75  RemoveDisplayList(itr->second);
76  }
77  ;
78  virtual void Visualize(Stg::Model* mod, Stg::Camera* cam) {
79  GLint OldDepthFunc;
80  glGetIntegerv(GL_DEPTH_FUNC, &OldDepthFunc);
81  glDepthFunc(GL_LEQUAL);
82  for (queuemap::iterator itr = ClientDisplayLists.begin(); itr
83  != ClientDisplayLists.end(); ++itr) {
84  glPushMatrix();
85  glTranslatef(0, 0, 0.01);// tiny Z offset raises rect above grid
86  glCallList(itr->second.DisplayList);
87  glPopMatrix();
88  }
89  glDepthFunc(OldDepthFunc);
90  }
91 
92  void Clear(MessageQueue * client) {
93  struct clientDisplaylist &list = GetDisplayList(client);
94  list.RenderItems.clear();
95  glNewList(list.DisplayList, GL_COMPILE );
96  glEndList();
97  }
98  ;
99 
100  bool HasActiveDisplayList(MessageQueue * client) {
101  queuemap::iterator found = ClientDisplayLists.find(client);
102  if (found == ClientDisplayLists.end())
103  return false;
104  else if (found->second.DisplayList == -1)
105  return false;
106  return true;
107  }
108 
109  struct clientDisplaylist & GetDisplayList(MessageQueue * client) {
110  queuemap::iterator found = ClientDisplayLists.find(client);
111  if (found == ClientDisplayLists.end()) // Display list not created yet
112  {
113  clientDisplaylist & clientDisp = ClientDisplayLists[client];
114  clientDisp.DisplayList = glGenLists(1);
115  return clientDisp;
116  }
117  else if (found->second.DisplayList == -1)
118  found->second.DisplayList = glGenLists(1);
119  return found->second;
120  }
121 
122  void BuildDisplayList(MessageQueue * client) {
123  struct clientDisplaylist &list = GetDisplayList(client);
124  glNewList(list.DisplayList, GL_COMPILE );
125  glPushMatrix();
126  for (vector<Message>::iterator itr = list.RenderItems.begin(); itr
127  != list.RenderItems.end(); ++itr)
128  RenderItem(*itr);
129  glPopMatrix();
130  glEndList();
131  }
132 
133  void RemoveDisplayList(struct clientDisplaylist & list) {
134  if (list.DisplayList > 0)
135  glDeleteLists(list.DisplayList, 1);
136  }
137 
138  virtual void AppendItem(MessageQueue * client, Message & item) {
139  struct clientDisplaylist & list = GetDisplayList(client);
140  list.RenderItems.push_back(item);
141  }
142  ;
143 
144  void Subscribe(QueuePointer &queue) {
145  if (queue == NULL)
146  return;
147  clientDisplaylist & clientDisp = ClientDisplayLists[queue.get()];
148  // delay creation of display list so we don't get race conditions on internal subscriptions.
149  clientDisp.DisplayList = -1;
150  }
151 
152  void Unsubscribe(QueuePointer &queue) {
153  if (queue == NULL)
154  return;
155  if (HasActiveDisplayList(queue.get()))
156  {
157  struct clientDisplaylist & list = GetDisplayList(queue.get());
158  RemoveDisplayList(list);
159  }
160  ClientDisplayLists.erase(queue.get());
161  }
162 
163  void glPlayerColour(const player_color_t & colour) {
164  glColor4f(static_cast<float> (colour.red) / 255.0,
165  static_cast<float> (colour.green) / 255.0,
166  static_cast<float> (colour.blue) / 255.0, 1
167  - static_cast<float> (colour.alpha) / 255.0);
168  }
169 
170  virtual void RenderItem(Message & item) = 0;
171 
172 private:
173  typedef map<MessageQueue *, struct clientDisplaylist> queuemap;
175 };
176 
178 public:
181  }
182  ;
184  }
185  ;
186 
187  void RenderItem(Message & item);
188 };
189 
191 public:
194  }
195  ;
197  }
198  ;
199 
200  void RenderItem(Message & item);
201 };
202 
204  StgDriver* driver, ConfigFile* cf, int section) :
205  InterfaceModel(addr, driver, cf, section, "") {
206  vis = new PlayerGraphics2dVis;
207  mod->AddVisualizer( vis, true );
208 }
209 
212  delete vis;
213 }
214 
215 void InterfaceGraphics2d::Subscribe(QueuePointer &queue) {
216  vis->Subscribe(queue);
217 }
218 
219 void InterfaceGraphics2d::Unsubscribe(QueuePointer &queue) {
220  vis->Unsubscribe(queue);
221 }
222 
223 int InterfaceGraphics2d::ProcessMessage(QueuePointer & resp_queue,
224  player_msghdr_t* hdr, void* data) {
225  if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
226  PLAYER_GRAPHICS2D_CMD_CLEAR, this->addr)) {
227  vis->Clear(resp_queue.get());
228  return 0; //ok
229  }
230 
231  if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
232  PLAYER_GRAPHICS2D_CMD_POINTS, this->addr)
233  || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
234  PLAYER_GRAPHICS2D_CMD_POLYLINE, this->addr)
235 #ifdef PLAYER_GRAPHICS2D_CMD_MULTILINE
236  || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
237  PLAYER_GRAPHICS2D_CMD_MULTILINE, this->addr)
238 #endif
239  || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
240  PLAYER_GRAPHICS2D_CMD_POLYGON, this->addr)) {
241  Message msg(*hdr, data);
242  vis->AppendItem(resp_queue.get(), msg);
243  vis->BuildDisplayList(resp_queue.get());
244  return 0;
245  }
246 
247  PLAYER_WARN2("stage graphics2d doesn't support message %d:%d.", hdr->type,
248  hdr->subtype);
249  return -1;
250 }
251 
252 void PlayerGraphics2dVis::RenderItem(Message & item) {
253  glDepthMask(GL_FALSE);
254  int type = item.GetHeader()->subtype;
255  switch (type) {
256  case PLAYER_GRAPHICS2D_CMD_POINTS: {
257  player_graphics2d_cmd_points_t
258  & data =
259  *reinterpret_cast<player_graphics2d_cmd_points_t*> (item.GetPayload());
260  glPlayerColour(data.color);
261  glBegin(GL_POINTS);
262  for (unsigned ii = 0; ii < data.points_count; ++ii)
263  glVertex3f(data.points[ii].px, data.points[ii].py, 0);
264  glEnd();
265  }
266  break;
267  case PLAYER_GRAPHICS2D_CMD_POLYLINE: {
268  player_graphics2d_cmd_polyline_t
269  & data =
270  *reinterpret_cast<player_graphics2d_cmd_polyline_t*> (item.GetPayload());
271  glPlayerColour(data.color);
272  glBegin(GL_LINE_STRIP);
273  for (unsigned ii = 0; ii < data.points_count; ++ii)
274  glVertex3f(data.points[ii].px, data.points[ii].py, 0);
275  glEnd();
276  }
277  break;
278 
279 #ifdef PLAYER_GRAPHICS2D_CMD_MULTILINE
280  case PLAYER_GRAPHICS2D_CMD_MULTILINE: {
281  player_graphics2d_cmd_multiline_t
282  & data =
283  *reinterpret_cast<player_graphics2d_cmd_multiline_t*> (item.GetPayload());
284  glPlayerColour(data.color);
285  glBegin(GL_LINES);
286  for (unsigned ii = 0; ii < data.points_count; ++ii)
287  glVertex3f(data.points[ii].px, data.points[ii].py, 0);
288  glEnd();
289  }
290  break;
291 #endif
292 
293 
294 
295 
296 
297 
298  case PLAYER_GRAPHICS2D_CMD_POLYGON: {
299  player_graphics2d_cmd_polygon_t
300  & data =
301  *reinterpret_cast<player_graphics2d_cmd_polygon_t*> (item.GetPayload());
302  if (data.filled) {
303  glPlayerColour(data.fill_color);
304  glBegin(GL_POLYGON);
305  for (unsigned ii = 0; ii < data.points_count; ++ii)
306  glVertex3f(data.points[ii].px, data.points[ii].py, 0);
307  glEnd();
308  }
309  glPlayerColour(data.color);
310  glBegin(GL_LINE_LOOP);
311  for (unsigned ii = 0; ii < data.points_count; ++ii)
312  glVertex3f(data.points[ii].px, data.points[ii].py, 0);
313  glEnd();
314  }
315  break;
316  }
317  glDepthMask(GL_TRUE);
318 
319 }
320 
322  StgDriver* driver, ConfigFile* cf, int section) :
323  InterfaceModel(addr, driver, cf, section, "") {
324  vis = new PlayerGraphics3dVis;
325  mod->AddVisualizer( vis, true );
326 }
327 
330  delete vis;
331 }
332 
333 void InterfaceGraphics3d::Subscribe(QueuePointer &queue) {
334  vis->Subscribe(queue);
335 }
336 
337 void InterfaceGraphics3d::Unsubscribe(QueuePointer &queue) {
338  vis->Unsubscribe(queue);
339 }
340 
341 int InterfaceGraphics3d::ProcessMessage(QueuePointer & resp_queue,
342  player_msghdr_t* hdr, void* data) {
343  if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
344  PLAYER_GRAPHICS3D_CMD_CLEAR, this->addr)) {
345  vis->Clear(resp_queue.get());
346  return 0; //ok
347  }
348 
349  if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
350  PLAYER_GRAPHICS3D_CMD_PUSH, this->addr) || Message::MatchMessage(
351  hdr, PLAYER_MSGTYPE_CMD, PLAYER_GRAPHICS3D_CMD_POP, this->addr)
352  || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
353  PLAYER_GRAPHICS3D_CMD_DRAW, this->addr)
354  || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
355  PLAYER_GRAPHICS3D_CMD_TRANSLATE, this->addr)
356  || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
357  PLAYER_GRAPHICS3D_CMD_ROTATE, this->addr)) {
358  Message msg(*hdr, data);
359  vis->AppendItem(resp_queue.get(), msg);
360  vis->BuildDisplayList(resp_queue.get());
361  return 0;
362  }
363 
364  PLAYER_WARN2("stage graphics2d doesn't support message %d:%d.", hdr->type,
365  hdr->subtype);
366  return -1;
367 }
368 
369 void PlayerGraphics3dVis::RenderItem(Message & item) {
370  int type = item.GetHeader()->subtype;
371  switch (type) {
372  case PLAYER_GRAPHICS3D_CMD_DRAW: {
373  player_graphics3d_cmd_draw_t
374  & data =
375  *reinterpret_cast<player_graphics3d_cmd_draw_t*> (item.GetPayload());
376  glPlayerColour(data.color);
377  switch (data.draw_mode) {
378  case PLAYER_DRAW_POINTS:
379  glBegin(GL_POINTS);
380  break;
381  case PLAYER_DRAW_LINES:
382  glBegin(GL_LINES);
383  break;
384  case PLAYER_DRAW_LINE_STRIP:
385  glBegin(GL_LINE_STRIP);
386  break;
387  case PLAYER_DRAW_LINE_LOOP:
388  glBegin(GL_LINE_LOOP);
389  break;
390  case PLAYER_DRAW_TRIANGLES:
391  glBegin(GL_TRIANGLES);
392  break;
393  case PLAYER_DRAW_TRIANGLE_STRIP:
394  glBegin(GL_TRIANGLE_STRIP);
395  break;
396  case PLAYER_DRAW_TRIANGLE_FAN:
397  glBegin(GL_TRIANGLE_FAN);
398  break;
399  case PLAYER_DRAW_QUADS:
400  glBegin(GL_QUADS);
401  break;
402  case PLAYER_DRAW_QUAD_STRIP:
403  glBegin(GL_QUAD_STRIP);
404  break;
405  case PLAYER_DRAW_POLYGON:
406  glBegin(GL_POLYGON);
407  break;
408  default:
409  fprintf(stderr,"Unknown graphics 3d draw mode\n");
410  return;
411  }
412  for (unsigned ii = 0; ii < data.points_count; ++ii)
413  glVertex3f(data.points[ii].px, data.points[ii].py,
414  data.points[ii].pz);
415  glEnd();
416  }
417  break;
418  case PLAYER_GRAPHICS3D_CMD_TRANSLATE: {
419  player_graphics3d_cmd_translate_t
420  & data =
421  *reinterpret_cast<player_graphics3d_cmd_translate_t*> (item.GetPayload());
422  glTranslatef(data.x, data.y, data.z);
423  }
424  break;
425  case PLAYER_GRAPHICS3D_CMD_ROTATE: {
426  player_graphics3d_cmd_rotate_t
427  & data =
428  *reinterpret_cast<player_graphics3d_cmd_rotate_t*> (item.GetPayload());
429  glRotatef(data.a, data.x, data.y, data.z);
430  }
431  break;
432  case PLAYER_GRAPHICS3D_CMD_PUSH: {
433  glPushMatrix();
434  }
435  break;
436  case PLAYER_GRAPHICS3D_CMD_POP: {
437  glPopMatrix();
438  }
439  break;
440  }
441 }
Model class
Definition: stage.hh:1742
virtual ~PlayerGraphicsVis(void)
Definition: p_graphics.cc:72
void RenderItem(Message &item)
Definition: p_graphics.cc:252
queuemap ClientDisplayLists
Definition: p_graphics.cc:174
virtual ~InterfaceGraphics2d(void)
Definition: p_graphics.cc:210
virtual int ProcessMessage(QueuePointer &resp_queue, player_msghdr *hdr, void *data)
Definition: p_graphics.cc:341
The Stage library uses its own namespace.
Definition: canvas.hh:8
PlayerGraphics3dVis * vis
Definition: p_driver.h:371
void BuildDisplayList(MessageQueue *client)
Definition: p_graphics.cc:122
map< MessageQueue *, struct clientDisplaylist > queuemap
Definition: p_graphics.cc:173
StgDriver * driver
Definition: p_driver.h:72
player_devaddr_t addr
Definition: p_driver.h:66
void RemoveVisualizer(Visualizer *custom_visual)
Definition: model_draw.cc:348
void RemoveDisplayList(struct clientDisplaylist &list)
Definition: p_graphics.cc:133
void Unsubscribe(QueuePointer &queue)
Definition: p_graphics.cc:152
bool HasActiveDisplayList(MessageQueue *client)
Definition: p_graphics.cc:100
struct clientDisplaylist & GetDisplayList(MessageQueue *client)
Definition: p_graphics.cc:109
virtual void Unsubscribe(void)
Definition: p_driver.cc:276
virtual int ProcessMessage(QueuePointer &resp_queue, player_msghdr *hdr, void *data)
Definition: p_graphics.cc:223
InterfaceGraphics2d(player_devaddr_t addr, StgDriver *driver, ConfigFile *cf, int section)
Definition: p_graphics.cc:203
void Clear(MessageQueue *client)
Definition: p_graphics.cc:92
void RenderItem(Message &item)
Definition: p_graphics.cc:369
virtual void Visualize(Stg::Model *mod, Stg::Camera *cam)
Definition: p_graphics.cc:78
void AddVisualizer(Visualizer *custom_visual, bool on_by_default)
Definition: model_draw.cc:322
virtual ~InterfaceGraphics3d(void)
Definition: p_graphics.cc:328
Stg::Model * mod
Definition: p_driver.h:115
InterfaceGraphics3d(player_devaddr_t addr, StgDriver *driver, ConfigFile *cf, int section)
Definition: p_graphics.cc:321
void glPlayerColour(const player_color_t &colour)
Definition: p_graphics.cc:163
virtual void Subscribe(void)
Definition: p_driver.cc:267
PlayerGraphics2dVis * vis
Definition: p_driver.h:354
virtual void AppendItem(MessageQueue *client, Message &item)
Definition: p_graphics.cc:138
void Subscribe(QueuePointer &queue)
Definition: p_graphics.cc:144
vector< Message > RenderItems
Definition: p_graphics.cc:61


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 Mon Jun 10 2019 15:06:09