Revision: 8055
http://playerstage.svn.sourceforge.net/playerstage/?rev=8055&view=rev
Author: rtv
Date: 2009-07-19 16:24:07 +0000 (Sun, 19 Jul 2009)
Log Message:
-----------
added missign file
Added Paths:
-----------
code/stage/trunk/libstageplugin/p_graphics.cc
Added: code/stage/trunk/libstageplugin/p_graphics.cc
===================================================================
--- code/stage/trunk/libstageplugin/p_graphics.cc
(rev 0)
+++ code/stage/trunk/libstageplugin/p_graphics.cc 2009-07-19 16:24:07 UTC
(rev 8055)
@@ -0,0 +1,396 @@
+/*
+ * Stage
+ * Copyright (C) Richard Vaughan
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ *
+ */
+
+/*
+ * Desc: A plugin driver for Player that gives access to Stage devices.
+ * Author: Richard Vaughan
+ * Date: 10 December 2004
+ * CVS: $Id: p_graphics3d.cc,v 1.2 2008-01-15 01:25:42 rtv Exp $
+ */
+
+#include "p_driver.h"
+
+#include <iostream>
+using namespace std;
+
+#ifdef G_OS_WIN32
+#define WIN32_LEAN_AND_MEAN 1
+#include <windows.h>
+#endif
+
+struct clientDisplaylist {
+ int DisplayList;
+ vector<Message> RenderItems;
+};
+
+class PlayerGraphicsVis: public Stg::Visualizer {
+private:
+
+public:
+ PlayerGraphicsVis() :
+ Stg::Visualizer("Graphics", "custom_vis") {
+ }
+ ;
+ virtual ~PlayerGraphicsVis(void) {
+ for (queuemap::iterator itr = ClientDisplayLists.begin(); itr
+ != ClientDisplayLists.end(); ++itr)
+ RemoveDisplayList(itr->second);
+ }
+ ;
+ virtual void Visualize(Stg::Model* mod, Stg::Camera* cam) {
+ GLint OldDepthFunc;
+ glGetIntegerv(GL_DEPTH_FUNC, &OldDepthFunc);
+ glDepthFunc(GL_LEQUAL);
+ for (queuemap::iterator itr = ClientDisplayLists.begin(); itr
+ != ClientDisplayLists.end(); ++itr) {
+ glPushMatrix();
+ glTranslatef(0, 0, 0.01);// tiny Z offset raises rect
above grid
+ glCallList(itr->second.DisplayList);
+ glPopMatrix();
+ }
+ glDepthFunc(OldDepthFunc);
+ }
+
+ void Clear(MessageQueue * client) {
+ struct clientDisplaylist &list = GetDisplayList(client);
+ list.RenderItems.clear();
+ glNewList(list.DisplayList, GL_COMPILE );
+ glEndList();
+ }
+ ;
+
+ bool HasActiveDisplayList(MessageQueue * client) {
+ queuemap::iterator found = ClientDisplayLists.find(client);
+ if (found == ClientDisplayLists.end())
+ return false;
+ else if (found->second.DisplayList == -1)
+ return false;
+ return true;
+ }
+
+ struct clientDisplaylist & GetDisplayList(MessageQueue * client) {
+ queuemap::iterator found = ClientDisplayLists.find(client);
+ if (found == ClientDisplayLists.end()) // Display list not
created yet
+ {
+ clientDisplaylist & clientDisp =
ClientDisplayLists[client];
+ clientDisp.DisplayList = glGenLists(1);
+ return clientDisp;
+ }
+ else if (found->second.DisplayList == -1)
+ found->second.DisplayList = glGenLists(1);
+ return found->second;
+ }
+
+ void BuildDisplayList(MessageQueue * client) {
+ struct clientDisplaylist &list = GetDisplayList(client);
+ glNewList(list.DisplayList, GL_COMPILE );
+ glPushMatrix();
+ for (vector<Message>::iterator itr = list.RenderItems.begin();
itr
+ != list.RenderItems.end(); ++itr)
+ RenderItem(*itr);
+ glPopMatrix();
+ glEndList();
+ }
+
+ void RemoveDisplayList(struct clientDisplaylist & list) {
+ if (list.DisplayList > 0)
+ glDeleteLists(list.DisplayList, 1);
+ }
+
+ virtual void AppendItem(MessageQueue * client, Message & item) {
+ struct clientDisplaylist & list = GetDisplayList(client);
+ list.RenderItems.push_back(item);
+ }
+ ;
+
+ void Subscribe(QueuePointer &queue) {
+ if (queue == NULL)
+ return;
+ clientDisplaylist & clientDisp =
ClientDisplayLists[queue.get()];
+ // delay creation of display list so we don't get race
conditions on internal subscriptions.
+ clientDisp.DisplayList = -1;
+ }
+
+ void Unsubscribe(QueuePointer &queue) {
+ if (queue == NULL)
+ return;
+ if (HasActiveDisplayList(queue.get()))
+ {
+ struct clientDisplaylist & list = GetDisplayList(queue.get());
+ RemoveDisplayList(list);
+ }
+ ClientDisplayLists.erase(queue.get());
+ }
+
+ void glPlayerColour(const player_color_t & colour) {
+ glColor4f(static_cast<float> (colour.red) / 255.0,
+ static_cast<float> (colour.green) / 255.0,
+ static_cast<float> (colour.blue) / 255.0, 1
+ - static_cast<float>
(colour.alpha) / 255.0);
+ }
+
+ virtual void RenderItem(Message & item) = 0;
+
+private:
+ typedef map<MessageQueue *, struct clientDisplaylist> queuemap;
+ queuemap ClientDisplayLists;
+};
+
+class PlayerGraphics2dVis: public PlayerGraphicsVis {
+public:
+ PlayerGraphics2dVis() :
+ PlayerGraphicsVis() {
+ }
+ ;
+ ~PlayerGraphics2dVis() {
+ }
+ ;
+
+ void RenderItem(Message & item);
+};
+
+class PlayerGraphics3dVis: public PlayerGraphicsVis {
+public:
+ PlayerGraphics3dVis() :
+ PlayerGraphicsVis() {
+ }
+ ;
+ ~PlayerGraphics3dVis() {
+ }
+ ;
+
+ void RenderItem(Message & item);
+};
+
+InterfaceGraphics2d::InterfaceGraphics2d(player_devaddr_t addr,
+ StgDriver* driver, ConfigFile* cf, int section) :
+ InterfaceModel(addr, driver, cf, section, Stg::MODEL_TYPE_PLAIN) {
+ vis = new PlayerGraphics2dVis;
+ mod->AddVisualizer( vis, true );
+}
+
+InterfaceGraphics2d::~InterfaceGraphics2d() {
+ mod->RemoveVisualizer(vis);
+ delete vis;
+}
+
+void InterfaceGraphics2d::Subscribe(QueuePointer &queue) {
+ vis->Subscribe(queue);
+}
+
+void InterfaceGraphics2d::Unsubscribe(QueuePointer &queue) {
+ vis->Unsubscribe(queue);
+}
+
+int InterfaceGraphics2d::ProcessMessage(QueuePointer & resp_queue,
+ player_msghdr_t* hdr, void* data) {
+ if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
+ PLAYER_GRAPHICS2D_CMD_CLEAR, this->addr)) {
+ vis->Clear(resp_queue.get());
+ return 0; //ok
+ }
+
+ if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
+ PLAYER_GRAPHICS2D_CMD_POINTS, this->addr)
+ || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
+ PLAYER_GRAPHICS2D_CMD_POLYLINE,
this->addr)
+ || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
+ PLAYER_GRAPHICS2D_CMD_POLYGON,
this->addr)) {
+ Message msg(*hdr, data);
+ vis->AppendItem(resp_queue.get(), msg);
+ vis->BuildDisplayList(resp_queue.get());
+ return 0;
+ }
+
+ PLAYER_WARN2("stage graphics2d doesn't support message %d:%d.",
hdr->type,
+ hdr->subtype);
+ return -1;
+}
+
+void PlayerGraphics2dVis::RenderItem(Message & item) {
+ glDepthMask(GL_FALSE);
+ int type = item.GetHeader()->subtype;
+ switch (type) {
+ case PLAYER_GRAPHICS2D_CMD_POINTS: {
+ player_graphics2d_cmd_points_t
+ & data =
+
*reinterpret_cast<player_graphics2d_cmd_points_t*> (item.GetPayload());
+ glPlayerColour(data.color);
+ glBegin(GL_POINTS);
+ for (unsigned ii = 0; ii < data.points_count; ++ii)
+ glVertex3f(data.points[ii].px, data.points[ii].py, 0);
+ glEnd();
+ }
+ break;
+ case PLAYER_GRAPHICS2D_CMD_POLYLINE: {
+ player_graphics2d_cmd_polyline_t
+ & data =
+
*reinterpret_cast<player_graphics2d_cmd_polyline_t*> (item.GetPayload());
+ glPlayerColour(data.color);
+ glBegin(GL_LINE_STRIP);
+ for (unsigned ii = 0; ii < data.points_count; ++ii)
+ glVertex3f(data.points[ii].px, data.points[ii].py, 0);
+ glEnd();
+ }
+ break;
+ case PLAYER_GRAPHICS2D_CMD_POLYGON: {
+ player_graphics2d_cmd_polygon_t
+ & data =
+
*reinterpret_cast<player_graphics2d_cmd_polygon_t*> (item.GetPayload());
+ if (data.filled) {
+ glPlayerColour(data.fill_color);
+ glBegin(GL_POLYGON);
+ for (unsigned ii = 0; ii < data.points_count; ++ii)
+ glVertex3f(data.points[ii].px,
data.points[ii].py, 0);
+ glEnd();
+ }
+ glPlayerColour(data.color);
+ glBegin(GL_LINE_LOOP);
+ for (unsigned ii = 0; ii < data.points_count; ++ii)
+ glVertex3f(data.points[ii].px, data.points[ii].py, 0);
+ glEnd();
+ }
+ break;
+ }
+ glDepthMask(GL_TRUE);
+
+}
+
+InterfaceGraphics3d::InterfaceGraphics3d(player_devaddr_t addr,
+ StgDriver* driver, ConfigFile* cf, int section) :
+ InterfaceModel(addr, driver, cf, section, Stg::MODEL_TYPE_PLAIN) {
+ vis = new PlayerGraphics3dVis;
+ mod->AddVisualizer( vis, true );
+}
+
+InterfaceGraphics3d::~InterfaceGraphics3d() {
+ mod->RemoveVisualizer(vis);
+ delete vis;
+}
+
+void InterfaceGraphics3d::Subscribe(QueuePointer &queue) {
+ vis->Subscribe(queue);
+}
+
+void InterfaceGraphics3d::Unsubscribe(QueuePointer &queue) {
+ vis->Unsubscribe(queue);
+}
+
+int InterfaceGraphics3d::ProcessMessage(QueuePointer & resp_queue,
+ player_msghdr_t* hdr, void* data) {
+ if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
+ PLAYER_GRAPHICS3D_CMD_CLEAR, this->addr)) {
+ vis->Clear(resp_queue.get());
+ return 0; //ok
+ }
+
+ if (Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
+ PLAYER_GRAPHICS3D_CMD_PUSH, this->addr) ||
Message::MatchMessage(
+ hdr, PLAYER_MSGTYPE_CMD, PLAYER_GRAPHICS3D_CMD_POP,
this->addr)
+ || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
+ PLAYER_GRAPHICS3D_CMD_DRAW, this->addr)
+ || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
+ PLAYER_GRAPHICS3D_CMD_TRANSLATE,
this->addr)
+ || Message::MatchMessage(hdr, PLAYER_MSGTYPE_CMD,
+ PLAYER_GRAPHICS3D_CMD_ROTATE,
this->addr)) {
+ Message msg(*hdr, data);
+ vis->AppendItem(resp_queue.get(), msg);
+ vis->BuildDisplayList(resp_queue.get());
+ return 0;
+ }
+
+ PLAYER_WARN2("stage graphics2d doesn't support message %d:%d.",
hdr->type,
+ hdr->subtype);
+ return -1;
+}
+
+void PlayerGraphics3dVis::RenderItem(Message & item) {
+ int type = item.GetHeader()->subtype;
+ switch (type) {
+ case PLAYER_GRAPHICS3D_CMD_DRAW: {
+ player_graphics3d_cmd_draw_t
+ & data =
+
*reinterpret_cast<player_graphics3d_cmd_draw_t*> (item.GetPayload());
+ glPlayerColour(data.color);
+ switch (data.draw_mode) {
+ case PLAYER_DRAW_POINTS:
+ glBegin(GL_POINTS);
+ break;
+ case PLAYER_DRAW_LINES:
+ glBegin(GL_LINES);
+ break;
+ case PLAYER_DRAW_LINE_STRIP:
+ glBegin(GL_LINE_STRIP);
+ break;
+ case PLAYER_DRAW_LINE_LOOP:
+ glBegin(GL_LINE_LOOP);
+ break;
+ case PLAYER_DRAW_TRIANGLES:
+ glBegin(GL_TRIANGLES);
+ break;
+ case PLAYER_DRAW_TRIANGLE_STRIP:
+ glBegin(GL_TRIANGLE_STRIP);
+ break;
+ case PLAYER_DRAW_TRIANGLE_FAN:
+ glBegin(GL_TRIANGLE_FAN);
+ break;
+ case PLAYER_DRAW_QUADS:
+ glBegin(GL_QUADS);
+ break;
+ case PLAYER_DRAW_QUAD_STRIP:
+ glBegin(GL_QUAD_STRIP);
+ break;
+ case PLAYER_DRAW_POLYGON:
+ glBegin(GL_POLYGON);
+ break;
+ default:
+ fprintf(stderr,"Unknown graphics 3d draw mode\n");
+ return;
+ }
+ for (unsigned ii = 0; ii < data.points_count; ++ii)
+ glVertex3f(data.points[ii].px, data.points[ii].py,
+ data.points[ii].pz);
+ glEnd();
+ }
+ break;
+ case PLAYER_GRAPHICS3D_CMD_TRANSLATE: {
+ player_graphics3d_cmd_translate_t
+ & data =
+
*reinterpret_cast<player_graphics3d_cmd_translate_t*> (item.GetPayload());
+ glTranslatef(data.x, data.y, data.z);
+ }
+ break;
+ case PLAYER_GRAPHICS3D_CMD_ROTATE: {
+ player_graphics3d_cmd_rotate_t
+ & data =
+
*reinterpret_cast<player_graphics3d_cmd_rotate_t*> (item.GetPayload());
+ glRotatef(data.a, data.x, data.y, data.z);
+ }
+ break;
+ case PLAYER_GRAPHICS3D_CMD_PUSH: {
+ glPushMatrix();
+ }
+ break;
+ case PLAYER_GRAPHICS3D_CMD_POP: {
+ glPopMatrix();
+ }
+ break;
+ }
+}
This was sent by the SourceForge.net collaborative development platform, the
world's largest Open Source development site.
------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge
This is your chance to win up to $100,000 in prizes! For a limited time,
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
Playerstage-commit mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/playerstage-commit