neoGFX
C++ GPU-oriented GUI library and app/game creation framework.
i_mesh.hpp
Go to the documentation of this file.
1 // i_mesh.hpp
2 /*
3  neogfx C++ GUI Library
4  Copyright (c) 2015 Leigh Johnston. All Rights Reserved.
5 
6  This program is free software: you can redistribute it and / or modify
7  it under the terms of the GNU General Public License as published by
8  the Free Software Foundation, either version 3 of the License, or
9  (at your option) any later version.
10 
11  This program is distributed in the hope that it will be useful,
12  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14  GNU General Public License for more details.
15 
16  You should have received a copy of the GNU General Public License
17  along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19 #pragma once
20 
21 #include <neogfx/neogfx.hpp>
22 #include <neolib/vecarray.hpp>
25 #include <neogfx/gfx/texture.hpp>
26 #include <neogfx/game/shapes.hpp>
27 
28 namespace neogfx
29 {
30  struct vertex
31  {
34  };
35  typedef std::vector<vertex> vertex_list;
36  typedef boost::optional<vertex_list> optional_vertex_list;
37  typedef vertex_list::size_type vertex_index;
38  typedef std::shared_ptr<vertex_list> vertex_list_pointer;
39  typedef std::array<vertex_index, 3> triangle;
40 
41  struct face
42  {
43  triangle vertices;
45  };
46 
47  class face_list
48  {
49  public:
50  struct no_container : std::logic_error { no_container() : std::logic_error("neogfx::face_list::no_container") {} };
51  public:
52  typedef std::vector<face> container;
53  typedef std::shared_ptr<container> container_pointer;
54  typedef container::const_iterator const_iterator;
55  typedef container::iterator iterator;
56  public:
58  {
59  }
60  face_list(container_pointer aFaces) :
61  iFaces{ aFaces }
62  {
63  }
64  face_list(const face_list& aOther, const_iterator aBegin, const_iterator aEnd) :
65  iFaces{ aOther.iFaces },
66  iBegin{ iFaces->begin() + (aBegin - iFaces->cbegin()) },
67  iEnd{ iFaces->begin() + (aEnd - iFaces->cbegin()) }
68  {
69  }
70  public:
71  bool empty() const
72  {
73  return iFaces == nullptr || iFaces->empty();
74  }
75  const_iterator cbegin() const
76  {
77  if (iFaces == nullptr)
78  throw no_container();
79  return iBegin != boost::none ? *iBegin : iFaces->cbegin();
80  }
81  const_iterator begin() const
82  {
83  return cbegin();
84  }
85  iterator begin()
86  {
87  if (iFaces == nullptr)
88  throw no_container();
89  return iBegin != boost::none ? *iBegin : iFaces->begin();
90  }
91  const_iterator cend() const
92  {
93  if (iFaces == nullptr)
94  throw no_container();
95  return iEnd != boost::none ? *iEnd : iFaces->cend();
96  }
97  const_iterator end() const
98  {
99  return cend();
100  }
101  iterator end()
102  {
103  if (iFaces == nullptr)
104  throw no_container();
105  return iEnd != boost::none ? *iEnd : iFaces->end();
106  }
107  const container& faces() const
108  {
109  if (iFaces == nullptr)
110  iFaces = std::make_shared<container>();
111  return *iFaces;
112  }
113  container& faces()
114  {
115  if (iFaces == nullptr)
116  iFaces = std::make_shared<container>();
117  iBegin = boost::none;
118  iEnd = boost::none;
119  return *iFaces;
120  }
121  private:
122  mutable container_pointer iFaces;
123  boost::optional<iterator> iBegin;
124  boost::optional<iterator> iEnd;
125  };
126 
127  inline void add_faces(vertex_list_pointer aVertices, face_list& aFaces, const std::vector<vec3>& aShapeVertices)
128  {
129  const std::size_t existingVertexCount = aVertices->size();
130  for (const auto& v : aShapeVertices)
131  aVertices->push_back(neogfx::vertex{ v });
132  for (neogfx::vertex_index vi = 1; vi + 1 < aShapeVertices.size(); ++vi)
133  aFaces.faces().push_back(neogfx::face{ { existingVertexCount + 0, existingVertexCount + vi, existingVertexCount + vi + 1 } });
134  }
135 
136  inline void add_faces(vertex_list_pointer aVertices, texture_list_pointer aTextures, face_list& aFaces, const neogfx::rect& aRect, const neogfx::i_texture& aTexture, bool aUpsideDown = false)
137  {
138  const std::size_t existingVertexCount = aVertices->size();
139  aTextures->push_back(neogfx::texture_source{ neogfx::to_texture_pointer(aTexture), neogfx::optional_rect{} });
142  const double zero = (!aUpsideDown ? 0.0 : 1.0);
143  const double one = (!aUpsideDown ? 1.0 : 0.0);
144  aVertices->push_back(neogfx::vertex{ rv[0], neogfx::vec2{ zero, zero } });
145  aVertices->push_back(neogfx::vertex{ rv[1], neogfx::vec2{ one, zero } });
146  aVertices->push_back(neogfx::vertex{ rv[2], neogfx::vec2{ zero, one } });
147  aFaces.faces().push_back(neogfx::face{ neogfx::triangle{ existingVertexCount + 0, existingVertexCount + 1, existingVertexCount + 2 }, aTextures->size() - 1 });
148  aVertices->push_back(neogfx::vertex{ rv[3], neogfx::vec2{ one, zero } });
149  aVertices->push_back(neogfx::vertex{ rv[4], neogfx::vec2{ one, one } });
150  aVertices->push_back(neogfx::vertex{ rv[5], neogfx::vec2{ zero, one } });
151  aFaces.faces().push_back(neogfx::face{ neogfx::triangle{ existingVertexCount + 3, existingVertexCount + 4, existingVertexCount + 5 }, aTextures->size() - 1 });
152  };
153 
154  class i_mesh
155  {
156  public:
157  struct no_textures : std::logic_error { no_textures() : std::logic_error("neogfx::i_mesh::no_textures") {} };
158  public:
159  virtual vertex_list_pointer vertices() const = 0;
160  virtual texture_list_pointer textures() const = 0;
161  virtual face_list faces() const = 0;
162  virtual face_list active_faces() const = 0;
163  virtual void activate_faces(face_list aActiveFaces) const = 0;
164  virtual mat44 transformation_matrix() const = 0;
165  virtual const vertex_list& transformed_vertices() const = 0;
166  public:
167  virtual void set_vertices(vertex_list_pointer aVertices) = 0;
168  virtual void set_textures(texture_list_pointer aTextures) = 0;
169  virtual void set_faces(face_list aFaces) = 0;
170  };
171 
173  {
174  public:
176  iMesh{ aMesh }, iPreviouslyActiveFaces{ aMesh.active_faces() }
177  {
178  iMesh.activate_faces(face_list{ aMesh.faces(), aBegin, aEnd });
179  }
181  {
182  iMesh.activate_faces(iPreviouslyActiveFaces);
183  }
184  private:
185  const i_mesh& iMesh;
186  face_list iPreviouslyActiveFaces;
187  };
188 
189  inline rect bounding_rect(const vertex_list& aVertices)
190  {
191  if (aVertices.empty())
192  return rect{};
193  point topLeft{ aVertices[0].coordinates.x, aVertices[0].coordinates.y };
194  point bottomRight = topLeft;
195  for (auto const& v : aVertices)
196  {
197  topLeft.x = std::min<coordinate>(topLeft.x, v.coordinates.x);
198  topLeft.y = std::min<coordinate>(topLeft.y, v.coordinates.y);
199  bottomRight.x = std::max<coordinate>(bottomRight.x, v.coordinates.x);
200  bottomRight.y = std::max<coordinate>(bottomRight.y, v.coordinates.y);
201  }
202  return rect{ topLeft, bottomRight };
203  }
204 }
std::shared_ptr< vertex_list > vertex_list_pointer
Definition: i_mesh.hpp:38
face_list(container_pointer aFaces)
Definition: i_mesh.hpp:60
coordinate_type x
iterator end()
Definition: i_mesh.hpp:101
const_iterator begin() const
Definition: i_mesh.hpp:81
std::shared_ptr< container > container_pointer
Definition: i_mesh.hpp:53
const container & faces() const
Definition: i_mesh.hpp:107
std::vector< face > container
Definition: i_mesh.hpp:52
boost::optional< rect > optional_rect
const_iterator cbegin() const
Definition: i_mesh.hpp:75
boost::optional< vertex_list > optional_vertex_list
Definition: i_mesh.hpp:36
iterator begin()
Definition: i_mesh.hpp:85
std::array< vertex_index, 3 > triangle
Definition: i_mesh.hpp:39
const_iterator cend() const
Definition: i_mesh.hpp:91
virtual face_list active_faces() const =0
vec3 coordinates
Definition: i_mesh.hpp:32
const_iterator end() const
Definition: i_mesh.hpp:97
void add_faces(vertex_list_pointer aVertices, face_list &aFaces, const std::vector< vec3 > &aShapeVertices)
Definition: i_mesh.hpp:127
container::const_iterator const_iterator
Definition: i_mesh.hpp:54
texture_list::size_type texture_index
Definition: texture.hpp:68
triangle vertices
Definition: i_mesh.hpp:43
std::vector< vertex > vertex_list
Definition: i_mesh.hpp:35
vertex_list::size_type vertex_index
Definition: i_mesh.hpp:37
std::shared_ptr< texture_list > texture_list_pointer
Definition: texture.hpp:69
scoped_faces(const i_mesh &aMesh, face_list::const_iterator aBegin, face_list::const_iterator aEnd)
Definition: i_mesh.hpp:175
bool empty() const
Definition: i_mesh.hpp:71
rect bounding_rect(const vertex_list &aVertices)
Definition: i_mesh.hpp:189
container::iterator iterator
Definition: i_mesh.hpp:55
void calc_rect_vertices(temp_vec3_buffer< VertexCount > &aResult, const rect &aRect, dimension aPixelAdjust, rect_type aType)
Definition: shapes.hpp:38
coordinate_type y
container & faces()
Definition: i_mesh.hpp:113
vec2 textureCoordinates
Definition: i_mesh.hpp:33
face_list(const face_list &aOther, const_iterator aBegin, const_iterator aEnd)
Definition: i_mesh.hpp:64
texture_index texture
Definition: i_mesh.hpp:44
std::pair< texture_pointer, optional_rect > texture_source
Definition: texture.hpp:65
texture_pointer to_texture_pointer(const i_texture &aTexture)
Definition: texture.hpp:71