1 /******************************************************************************
2 
3   This source file is part of the Avogadro project.
4 
5   Copyright 2013 Kitware, Inc.
6 
7   This source code is released under the New BSD License, (the "License").
8 
9   Unless required by applicable law or agreed to in writing, software
10   distributed under the License is distributed on an "AS IS" BASIS,
11   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12   See the License for the specific language governing permissions and
13   limitations under the License.
14 
15 ******************************************************************************/
16 
17 #ifndef AVOGADRO_RENDERING_LINESTRIPGEOMETRY_H
18 #define AVOGADRO_RENDERING_LINESTRIPGEOMETRY_H
19 
20 #include "drawable.h"
21 
22 #include <avogadro/core/array.h>
23 
24 namespace Avogadro {
25 namespace Rendering {
26 
27 /**
28  * @class LineStripGeometry linestripgeometry.h
29  * <avogadro/rendering/linestripgeometry.h>
30  * @brief The LineStripGeometry class is used to store sets of line strips.
31  */
32 
33 class AVOGADRORENDERING_EXPORT LineStripGeometry : public Drawable
34 {
35 public:
36   struct PackedVertex
37   {                  // 16 bytes total:
38     Vector3f vertex; // 12 bytes
39     Vector4ub color; //  4 bytes
40 
PackedVertexPackedVertex41     PackedVertex(const Vector3f& v, const Vector4ub& c)
42       : vertex(v)
43       , color(c)
44     {}
vertexOffsetPackedVertex45     static int vertexOffset() { return 0; }
colorOffsetPackedVertex46     static int colorOffset() { return static_cast<int>(sizeof(Vector3f)); }
47   };
48 
49   static const size_t InvalidIndex;
50 
51   LineStripGeometry();
52   LineStripGeometry(const LineStripGeometry& other);
53   ~LineStripGeometry() override;
54 
55   LineStripGeometry& operator=(LineStripGeometry);
56   friend void swap(LineStripGeometry& lhs, LineStripGeometry& rhs);
57 
58   /**
59    * Accept a visit from our friendly visitor.
60    */
61   void accept(Visitor&) override;
62 
63   /**
64    * @brief Render the line strips.
65    * @param camera The current camera to be used for rendering.
66    */
67   void render(const Camera& camera) override;
68 
69   /**
70    * Clear the contents of the node.
71    */
72   void clear() override;
73 
74   /**
75    * Add a complete line strip to the object.
76    * @param vertices The 3D vertices which will be connected to form the line
77    * strip.
78    * @param color Vertex color. If not specified, use the current color() and
79    * opacity(). If the 3 component color is set, the current opacity() is used.
80    * @param lineWidth The width of the line strip.
81    * @note All arrays must be the same length, or this function call will fail,
82    * returning InvalidIndex.
83    * @return The index of the first vertex added by this call.
84    * @{
85    */
86   size_t addLineStrip(const Core::Array<Vector3f>& vertices,
87                       const Core::Array<Vector4ub>& color, float lineWidth);
88   size_t addLineStrip(const Core::Array<Vector3f>& vertices,
89                       const Core::Array<Vector3ub>& color, float lineWidth);
90   size_t addLineStrip(const Core::Array<Vector3f>& vertices, float lineWidth);
91   /** @} */
92 
93   /**
94    * The default color of the lines. This is used to set the color of new
95    * vertices when no explicit vertex color is specified.
96    * @{
97    */
setColor(const Vector3ub & c)98   void setColor(const Vector3ub& c) { m_color = c; }
color()99   Vector3ub color() const { return m_color; }
100   /** @} */
101 
102   /**
103    * The default opacity of the lines. This is used when either no explicit
104    * vertex color is specified, or a three component color is used.
105    * @{
106    */
setOpacity(unsigned char opacity_)107   void setOpacity(unsigned char opacity_) { m_opacity = opacity_; }
opacity()108   unsigned char opacity() const { return m_opacity; }
109   /** @} */
110 
111   /** The vertex array. */
vertices()112   Core::Array<PackedVertex> vertices() const { return m_vertices; }
113 
114 private:
115   /**
116    * @brief Update the VBOs, IBOs etc ready for rendering.
117    */
118   void update();
119 
120   Core::Array<PackedVertex> m_vertices;
121   Core::Array<unsigned int> m_lineStarts;
122   Core::Array<float> m_lineWidths;
123 
124   Vector3ub m_color;
125   unsigned char m_opacity;
126 
127   bool m_dirty;
128 
129   class Private;
130   Private* d;
131 };
132 
133 inline LineStripGeometry& LineStripGeometry::operator=(LineStripGeometry other)
134 {
135   using std::swap;
136   swap(*this, other);
137   return *this;
138 }
139 
swap(LineStripGeometry & lhs,LineStripGeometry & rhs)140 inline void swap(LineStripGeometry& lhs, LineStripGeometry& rhs)
141 {
142   using std::swap;
143   swap(static_cast<Drawable&>(lhs), static_cast<Drawable&>(rhs));
144   swap(lhs.m_vertices, rhs.m_vertices);
145   swap(lhs.m_lineStarts, rhs.m_lineStarts);
146   swap(lhs.m_lineWidths, rhs.m_lineWidths);
147   swap(lhs.m_color, rhs.m_color);
148   swap(lhs.m_opacity, rhs.m_opacity);
149   lhs.m_dirty = rhs.m_dirty = true;
150 }
151 
152 } // End namespace Rendering
153 } // End namespace Avogadro
154 
155 #endif // AVOGADRO_RENDERING_LINESTRIPGEOMETRY_H
156