SUMO - Simulation of Urban MObility
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Modules Pages
GUIPolygon.cpp
Go to the documentation of this file.
1 /****************************************************************************/
10 // The GUI-version of a polygon
11 /****************************************************************************/
12 // SUMO, Simulation of Urban MObility; see http://sumo.dlr.de/
13 // Copyright (C) 2001-2016 DLR (http://www.dlr.de/) and contributors
14 /****************************************************************************/
15 //
16 // This file is part of SUMO.
17 // SUMO is free software: you can redistribute it and/or modify
18 // it under the terms of the GNU General Public License as published by
19 // the Free Software Foundation, either version 3 of the License, or
20 // (at your option) any later version.
21 //
22 /****************************************************************************/
23 
24 // ===========================================================================
25 // included modules
26 // ===========================================================================
27 #ifdef _MSC_VER
28 #include <windows_config.h>
29 #else
30 #include <config.h>
31 #endif
32 
33 #include <string>
34 #include "GUIPolygon.h"
40 #include <utils/gui/div/GLHelper.h>
42 
43 #ifdef CHECK_MEMORY_LEAKS
44 #include <foreign/nvwa/debug_new.h>
45 #endif // CHECK_MEMORY_LEAKS
46 
47 //#define GUIPolygon_DEBUG_DRAW_VERTICES
48 
49 // ===========================================================================
50 // method definitions
51 // ===========================================================================
52 GUIPolygon::GUIPolygon(const std::string& id, const std::string& type,
53  const RGBColor& color, const PositionVector& shape, bool fill,
54  SUMOReal layer, SUMOReal angle, const std::string& imgFile):
55  Polygon(id, type, color, shape, fill, layer, angle, imgFile),
57  myDisplayList(0),
58  myLineWidth(1) // m
59 
60 {}
61 
62 
64 
65 
66 
69  GUISUMOAbstractView& parent) {
70  GUIGLObjectPopupMenu* ret = new GUIGLObjectPopupMenu(app, parent, *this);
71  buildPopupHeader(ret, app, false);
72  FXString t(myType.c_str());
73  new FXMenuCommand(ret, "(" + t + ")", 0, 0, 0);
74  new FXMenuSeparator(ret);
78  buildPositionCopyEntry(ret, false);
79  return ret;
80 }
81 
82 
86  return 0;
87 }
88 
89 
92  Boundary b;
94  b.grow(2);
95  return b;
96 }
97 
98 
99 void APIENTRY beginCallback(GLenum which) {
100  glBegin(which);
101 }
102 
103 void APIENTRY errorCallback(GLenum errorCode) {
104  const GLubyte* estring;
105 
106  estring = gluErrorString(errorCode);
107  fprintf(stderr, "Tessellation Error: %s\n", estring);
108  exit(0);
109 }
110 
111 void APIENTRY endCallback(void) {
112  glEnd();
113 }
114 
115 void APIENTRY vertexCallback(GLvoid* vertex) {
116  glVertex3dv((GLdouble*) vertex);
117 }
118 
119 void APIENTRY combineCallback(GLdouble coords[3],
120  GLdouble* vertex_data[4],
121  GLfloat weight[4], GLdouble** dataOut) {
122  UNUSED_PARAMETER(weight);
123  UNUSED_PARAMETER(*vertex_data);
124  GLdouble* vertex;
125 
126  vertex = (GLdouble*) malloc(7 * sizeof(GLdouble));
127 
128  vertex[0] = coords[0];
129  vertex[1] = coords[1];
130  vertex[2] = coords[2];
131  *dataOut = vertex;
132 }
133 
134 
135 GLfloat INV_POLY_TEX_DIM = 1.0 / 256.0;
136 GLfloat xPlane[] = {INV_POLY_TEX_DIM, 0.0, 0.0, 0.0};
137 GLfloat yPlane[] = {0.0, INV_POLY_TEX_DIM, 0.0, 0.0};
138 
139 void
141  if (s.polySize.getExaggeration(s) == 0) {
142  return;
143  }
144  Boundary boundary = myShape.getBoxBoundary();
145  if (s.scale * MAX2(boundary.getWidth(), boundary.getHeight()) < s.polySize.minSize) {
146  return;
147  }
148  if (getFill()) {
149  if (myShape.size() < 3) {
150  return;
151  }
152  } else {
153  if (myShape.size() < 2) {
154  return;
155  }
156  }
158  //if (myDisplayList == 0 || (!getFill() && myLineWidth != s.polySize.getExaggeration(s))) {
159  // storeTesselation(s.polySize.getExaggeration(s));
160  //}
161  glPushName(getGlID());
162  glPushMatrix();
163  glTranslated(0, 0, getLayer());
164  glRotated(-getNaviDegree(), 0, 0, 1);
166 
167  int textureID = -1;
168  if (getFill()) {
169  const std::string& file = getImgFile();
170  if (file != "") {
171  textureID = GUITexturesHelper::getTextureID(file, true);
172  }
173  }
174  // init generation of texture coordinates
175  if (textureID >= 0) {
176  glEnable(GL_TEXTURE_2D);
177  glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
178  glDisable(GL_CULL_FACE);
179  glDisable(GL_DEPTH_TEST); // without DEPTH_TEST vehicles may be drawn below roads
180  glDisable(GL_LIGHTING);
181  glDisable(GL_COLOR_MATERIAL);
182  glDisable(GL_ALPHA_TEST);
183  glEnable(GL_BLEND);
184  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
185  glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
186  glBindTexture(GL_TEXTURE_2D, textureID);
187  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
188  glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
189  // http://www.gamedev.net/topic/133564-glutesselation-and-texture-mapping/
190  glEnable(GL_TEXTURE_GEN_S);
191  glEnable(GL_TEXTURE_GEN_T);
192  glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
193  glTexGenfv(GL_S, GL_OBJECT_PLANE, xPlane);
194  glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR);
195  glTexGenfv(GL_T, GL_OBJECT_PLANE, yPlane);
196  }
197  // recall tesselation
198  //glCallList(myDisplayList);
200  // de-init generation of texture coordinates
201  if (textureID >= 0) {
202  glEnable(GL_DEPTH_TEST);
203  glBindTexture(GL_TEXTURE_2D, 0);
204  glDisable(GL_TEXTURE_2D);
205  glDisable(GL_TEXTURE_GEN_S);
206  glDisable(GL_TEXTURE_GEN_T);
207  }
208 #ifdef GUIPolygon_DEBUG_DRAW_VERTICES
210 #endif
211  glPopMatrix();
212  const Position namePos = myShape.getPolygonCenter();
213  drawName(namePos, s.scale, s.polyName);
214  if (s.polyType.show) {
215  GLHelper::drawText(myType, namePos + Position(0, -0.6 * s.polyType.size / s.scale),
217  }
218  glPopName();
219 }
220 
221 
222 void
225  Polygon::setShape(shape);
226  //storeTesselation(myLineWidth);
227 }
228 
229 
230 void
232  if (getFill()) {
233  // draw the tesselated shape
234  double* points = new double[myShape.size() * 3];
235  GLUtesselator* tobj = gluNewTess();
236  gluTessCallback(tobj, GLU_TESS_VERTEX, (GLvoid(APIENTRY*)()) &glVertex3dv);
237  gluTessCallback(tobj, GLU_TESS_BEGIN, (GLvoid(APIENTRY*)()) &beginCallback);
238  gluTessCallback(tobj, GLU_TESS_END, (GLvoid(APIENTRY*)()) &endCallback);
239  //gluTessCallback(tobj, GLU_TESS_ERROR, (GLvoid (APIENTRY*) ()) &errorCallback);
240  gluTessCallback(tobj, GLU_TESS_COMBINE, (GLvoid(APIENTRY*)()) &combineCallback);
241  gluTessProperty(tobj, GLU_TESS_WINDING_RULE, GLU_TESS_WINDING_ODD);
242  gluTessBeginPolygon(tobj, NULL);
243  gluTessBeginContour(tobj);
244  for (int i = 0; i != (int)myShape.size(); ++i) {
245  points[3 * i] = myShape[(int) i].x();
246  points[3 * i + 1] = myShape[(int) i].y();
247  points[3 * i + 2] = 0;
248  gluTessVertex(tobj, points + 3 * i, points + 3 * i);
249  }
250  gluTessEndContour(tobj);
251 
252  gluTessEndPolygon(tobj);
253  gluDeleteTess(tobj);
254  delete[] points;
255 
256  } else {
258  GLHelper::drawBoxLines(myShape, lineWidth);
259  }
260  //std::cout << "OpenGL says: '" << gluErrorString(glGetError()) << "'\n";
261 }
262 
263 
264 void
266  if (myDisplayList > 0) {
267  glDeleteLists(myDisplayList, 1);
268  }
269  myDisplayList = glGenLists(1);
270  if (myDisplayList == 0) {
271  throw ProcessError("GUIPolygon::storeTesselation() could not create display list");
272  }
273  glNewList(myDisplayList, GL_COMPILE);
274  performTesselation(lineWidth);
275  glEndList();
276 }
277 
278 
279 /****************************************************************************/
280 
SUMOReal getExaggeration(const GUIVisualizationSettings &s, SUMOReal factor=20) const
return the drawing size including exaggeration and constantSize values
SUMOReal getHeight() const
Returns the height of the boundary (y-axis)
Definition: Boundary.cpp:172
const std::string & getImgFile() const
Returns the imgFile of the Shape.
Definition: Shape.h:101
SUMOReal getWidth() const
Returns the width of the boudary (x-axis)
Definition: Boundary.cpp:166
a polygon
void buildNameCopyPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds entries which allow to copy the name / typed name into the clipboard.
GLfloat xPlane[]
Definition: GUIPolygon.cpp:136
static void debugVertices(const PositionVector &shape, SUMOReal size, SUMOReal layer=256)
draw vertex numbers for the given shape (in a random color)
Definition: GLHelper.cpp:518
virtual void drawGL(const GUIVisualizationSettings &s) const
Draws the object.
Definition: GUIPolygon.cpp:140
Stores the information about how to visualize structures.
SUMOReal minSize
The minimum size to draw this object.
static void drawBoxLines(const PositionVector &geom, const std::vector< SUMOReal > &rots, const std::vector< SUMOReal > &lengths, SUMOReal width, int cornerDetail=0, SUMOReal offset=0)
Draws thick lines.
Definition: GLHelper.cpp:176
void buildCenterPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to center to the object.
T MAX2(T a, T b)
Definition: StdDefs.h:75
GUIPolygon(const std::string &id, const std::string &type, const RGBColor &color, const PositionVector &shape, bool fill, SUMOReal layer=0, SUMOReal angle=0, const std::string &imgFile="")
Constructor.
Definition: GUIPolygon.cpp:52
static void drawText(const std::string &text, const Position &pos, const SUMOReal layer, const SUMOReal size, const RGBColor &col=RGBColor::BLACK, const SUMOReal angle=0)
draw Text with given parameters
Definition: GLHelper.cpp:460
void buildPositionCopyEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to copy the cursor position if geo projection is used, also builds an entry for copying the geo-position.
GUIGlID getGlID() const
Returns the numerical id of the object.
#define UNUSED_PARAMETER(x)
Definition: StdDefs.h:39
A class that stores a 2D geometrical boundary.
Definition: Boundary.h:48
GLuint myDisplayList
id of the display list for the cached tesselation
Definition: GUIPolygon.h:125
SUMOReal scale
information about a lane's width (temporary, used for a single view)
std::string myType
The type of the Shape.
Definition: Shape.h:158
GUIVisualizationSizeSettings polySize
A 2D- or 3D-polygon.
Definition: Polygon.h:57
Boundary getCenteringBoundary() const
Returns the boundary to which the view shall be centered in order to show the object.
Definition: GUIPolygon.cpp:91
void performTesselation(SUMOReal lineWidth) const
Definition: GUIPolygon.cpp:231
static void setColor(const RGBColor &c)
Sets the gl-color to this value.
Definition: GLHelper.cpp:443
A point in 2D or 3D with translation and scaling methods.
Definition: Position.h:46
A list of positions.
GUIVisualizationTextSettings polyType
static int getTextureID(const std::string &filename, const bool mirrorX=false)
return texture id for the given filename (initialize on first use)
GUIParameterTableWindow * getParameterWindow(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own parameter window.
Definition: GUIPolygon.cpp:84
void storeTesselation(SUMOReal lineWidth) const
store the drawing commands in a display list
Definition: GUIPolygon.cpp:265
virtual void setShape(const PositionVector &shape)
set a new shape and update the tesselation
Definition: GUIPolygon.cpp:223
void drawName(const Position &pos, const SUMOReal scale, const GUIVisualizationTextSettings &settings, const SUMOReal angle=0) const
draw name of item
const RGBColor & getColor() const
Returns the color of the Shape.
Definition: Shape.h:79
GLfloat INV_POLY_TEX_DIM
Definition: GUIPolygon.cpp:135
SUMOReal myLineWidth
the previous line width for deciding whether the display list must be refreshed
Definition: GUIPolygon.h:128
void APIENTRY beginCallback(GLenum which)
Definition: GUIPolygon.cpp:99
Boundary & grow(SUMOReal by)
extends the boundary by the given amount
Definition: Boundary.cpp:232
void add(SUMOReal x, SUMOReal y, SUMOReal z=0)
Makes the boundary include the given coordinate.
Definition: Boundary.cpp:90
void APIENTRY endCallback(void)
Definition: GUIPolygon.cpp:111
void APIENTRY combineCallback(GLdouble coords[3], GLdouble *vertex_data[4], GLfloat weight[4], GLdouble **dataOut)
Definition: GUIPolygon.cpp:119
~GUIPolygon()
Destructor.
Definition: GUIPolygon.cpp:63
A mutex encapsulator which locks/unlocks the given mutex on construction/destruction, respectively.
Definition: AbstractMutex.h:71
The popup menu of a globject.
void buildSelectionPopupEntry(GUIGLObjectPopupMenu *ret, bool addSeparator=true)
Builds an entry which allows to (de)select the object.
void APIENTRY vertexCallback(GLvoid *vertex)
Definition: GUIPolygon.cpp:115
MFXMutex myLock
The mutex used to avoid concurrent updates of the shape.
Definition: GUIPolygon.h:122
static void drawLine(const Position &beg, SUMOReal rot, SUMOReal visLength)
Draws a thin line.
Definition: GLHelper.cpp:269
#define SUMOReal
Definition: config.h:214
empty max
SUMOReal getLayer() const
Returns the layer of the Shape.
Definition: Shape.h:87
Position getPolygonCenter() const
Returns the arithmetic of all corner points.
Boundary getBoxBoundary() const
Returns a boundary enclosing this list of lines.
A window containing a gl-object's parameter.
PositionVector myShape
The positions of the polygon.
Definition: Polygon.h:128
bool getFill() const
Returns whether the polygon is filled.
Definition: Polygon.h:95
SUMOReal getNaviDegree() const
Returns the angle of the Shape in navigational degrees.
Definition: Shape.h:94
GLfloat yPlane[]
Definition: GUIPolygon.cpp:137
GUIGLObjectPopupMenu * getPopUpMenu(GUIMainWindow &app, GUISUMOAbstractView &parent)
Returns an own popup-menu.
Definition: GUIPolygon.cpp:68
void buildPopupHeader(GUIGLObjectPopupMenu *ret, GUIMainWindow &app, bool addSeparator=true)
Builds the header.
void APIENTRY errorCallback(GLenum errorCode)
Definition: GUIPolygon.cpp:103
GUIVisualizationTextSettings polyName