KiCad PCB EDA Suite
vertex_manager.cpp
Go to the documentation of this file.
1 /*
2  * This program source code file is part of KiCad, a free EDA CAD application.
3  *
4  * Copyright (C) 2013-2016 CERN
5  * @author Maciej Suminski <maciej.suminski@cern.ch>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
34 #include <gal/opengl/gpu_manager.h>
35 #include <gal/opengl/vertex_item.h>
36 #include <confirm.h>
37 
38 using namespace KIGFX;
39 
41  m_noTransform( true ), m_transform( 1.0f ), m_reserved( NULL ), m_reservedSpace( 0 )
42 {
43  m_container.reset( VERTEX_CONTAINER::MakeContainer( aCached ) );
44  m_gpu.reset( GPU_MANAGER::MakeManager( m_container.get() ) );
45 
46  // There is no shader used by default
47  for( unsigned int i = 0; i < SHADER_STRIDE; ++i )
48  m_shader[i] = 0.0f;
49 }
50 
51 
53 {
54  m_container->Map();
55 }
56 
57 
59 {
60  m_container->Unmap();
61 }
62 
63 
64 bool VERTEX_MANAGER::Reserve( unsigned int aSize )
65 {
66  assert( m_reservedSpace == 0 && m_reserved == NULL );
67 
68  // flag to avoid hanging by calling DisplayError too many times:
69  static bool show_err = true;
70 
71  m_reserved = m_container->Allocate( aSize );
72 
73  if( m_reserved == NULL )
74  {
75  if( show_err )
76  {
77  DisplayError( NULL, wxT( "VERTEX_MANAGER::Reserve: Vertex allocation error" ) );
78  show_err = false;
79  }
80 
81  return false;
82  }
83 
84  m_reservedSpace = aSize;
85 
86  return true;
87 }
88 
89 
90 bool VERTEX_MANAGER::Vertex( GLfloat aX, GLfloat aY, GLfloat aZ )
91 {
92  // flag to avoid hanging by calling DisplayError too many times:
93  static bool show_err = true;
94 
95  // Obtain the pointer to the vertex in the currently used container
96  VERTEX* newVertex;
97 
98  if( m_reservedSpace > 0 )
99  {
100  newVertex = m_reserved++;
101  --m_reservedSpace;
102 
103  if( m_reservedSpace == 0 )
104  m_reserved = NULL;
105  }
106  else
107  {
108  newVertex = m_container->Allocate( 1 );
109  }
110 
111  if( newVertex == NULL )
112  {
113  if( show_err )
114  {
115  DisplayError( NULL, wxT( "VERTEX_MANAGER::Vertex: Vertex allocation error" ) );
116  show_err = false;
117  }
118 
119  return false;
120  }
121 
122  putVertex( *newVertex, aX, aY, aZ );
123 
124  return true;
125 }
126 
127 
128 bool VERTEX_MANAGER::Vertices( const VERTEX aVertices[], unsigned int aSize )
129 {
130  // flag to avoid hanging by calling DisplayError too many times:
131  static bool show_err = true;
132 
133  // Obtain pointer to the vertex in currently used container
134  VERTEX* newVertex = m_container->Allocate( aSize );
135 
136  if( newVertex == NULL )
137  {
138  if( show_err )
139  {
140  DisplayError( NULL, wxT( "VERTEX_MANAGER::Vertices: Vertex allocation error" ) );
141  show_err = false;
142  }
143 
144  return false;
145  }
146 
147  // Put vertices in already allocated memory chunk
148  for( unsigned int i = 0; i < aSize; ++i )
149  {
150  putVertex( newVertex[i], aVertices[i].x, aVertices[i].y, aVertices[i].z );
151  }
152 
153  return true;
154 }
155 
156 
158 {
159  m_container->SetItem( &aItem );
160 }
161 
162 
164 {
165  m_container->FinishItem();
166 }
167 
168 
170 {
171  m_container->Delete( &aItem );
172 }
173 
174 
175 void VERTEX_MANAGER::ChangeItemColor( const VERTEX_ITEM& aItem, const COLOR4D& aColor ) const
176 {
177  unsigned int size = aItem.GetSize();
178  unsigned int offset = aItem.GetOffset();
179 
180  VERTEX* vertex = m_container->GetVertices( offset );
181 
182  for( unsigned int i = 0; i < size; ++i )
183  {
184  vertex->r = aColor.r * 255.0;
185  vertex->g = aColor.g * 255.0;
186  vertex->b = aColor.b * 255.0;
187  vertex->a = aColor.a * 255.0;
188  vertex++;
189  }
190 
191  m_container->SetDirty();
192 }
193 
194 
195 void VERTEX_MANAGER::ChangeItemDepth( const VERTEX_ITEM& aItem, GLfloat aDepth ) const
196 {
197  unsigned int size = aItem.GetSize();
198  unsigned int offset = aItem.GetOffset();
199 
200  VERTEX* vertex = m_container->GetVertices( offset );
201 
202  for( unsigned int i = 0; i < size; ++i )
203  {
204  vertex->z = aDepth;
205  vertex++;
206  }
207 
208  m_container->SetDirty();
209 }
210 
211 
213 {
214  if( aItem.GetSize() == 0 )
215  return NULL; // The item is not stored in the container
216 
217  return m_container->GetVertices( aItem.GetOffset() );
218 }
219 
220 
221 void VERTEX_MANAGER::SetShader( SHADER& aShader ) const
222 {
223  m_gpu->SetShader( aShader );
224 }
225 
226 
228 {
229  m_container->Clear();
230 }
231 
232 
234 {
235  m_gpu->BeginDrawing();
236 }
237 
238 
239 void VERTEX_MANAGER::DrawItem( const VERTEX_ITEM& aItem ) const
240 {
241  int size = aItem.GetSize();
242  int offset = aItem.GetOffset();
243 
244  m_gpu->DrawIndices( offset, size );
245 }
246 
247 
249 {
250  m_gpu->EndDrawing();
251 }
252 
253 
254 void VERTEX_MANAGER::putVertex( VERTEX& aTarget, GLfloat aX, GLfloat aY, GLfloat aZ ) const
255 {
256  // Modify the vertex according to the currently used transformations
257  if( m_noTransform )
258  {
259  // Simply copy coordinates, when the transform matrix is the identity matrix
260  aTarget.x = aX;
261  aTarget.y = aY;
262  aTarget.z = aZ;
263  }
264  else
265  {
266  // Apply transformations
267  glm::vec4 transVertex( aX, aY, aZ, 1.0f );
268  transVertex = m_transform * transVertex;
269 
270  aTarget.x = transVertex.x;
271  aTarget.y = transVertex.y;
272  aTarget.z = transVertex.z;
273  }
274 
275  // Apply currently used color
276  aTarget.r = m_color[0];
277  aTarget.g = m_color[1];
278  aTarget.b = m_color[2];
279  aTarget.a = m_color[3];
280 
281  // Apply currently used shader
282  for( unsigned int j = 0; j < SHADER_STRIDE; ++j )
283  {
284  aTarget.shader[j] = m_shader[j];
285  }
286 }
void FreeItem(VERTEX_ITEM &aItem) const
Function FreeItem() frees the memory occupied by the item, so it is no longer stored in the container...
VERTEX * GetVertices(const VERTEX_ITEM &aItem) const
Function GetVertices() returns a pointer to the vertices owned by an item.
static VERTEX_CONTAINER * MakeContainer(bool aCached)
Returns a pointer to a new container of an appropriate type.
GLfloat shader[4]
Definition: vertex_common.h:54
void Clear() const
Function Clear() removes all the stored vertices from the container.
void ChangeItemDepth(const VERTEX_ITEM &aItem, GLfloat aDepth) const
Function ChangeItemDepth() changes the depth of all vertices owned by an item.
Class CAIRO_GAL is the cairo implementation of the graphics abstraction layer.
Definition: class_module.h:58
Data structure for vertices {X,Y,Z,R,G,B,A,shader¶m}
Definition: vertex_common.h:50
This file is part of the common library.
std::shared_ptr< VERTEX_CONTAINER > m_container
Container for vertices, may be cached or noncached.
bool Reserve(unsigned int aSize)
Function Reserve() allocates space for vertices, so it will be used with subsequent Vertex() calls...
GLfloat m_shader[SHADER_STRIDE]
Currently used shader and its parameters.
bool Vertex(const VERTEX &aVertex)
Function Vertex() adds a vertex with the given coordinates to the currently set item.
Class to control vertex container and GPU with possibility of emulating old-style OpenGL 1...
double g
Green component.
Definition: color4d.h:287
void SetItem(VERTEX_ITEM &aItem) const
Function SetItem() sets an item to start its modifications.
bool m_noTransform
State machine variables True in case there is no need to transform vertices.
double b
Blue component.
Definition: color4d.h:288
glm::mat4 m_transform
Currently used transform matrix.
double a
Alpha component.
Definition: color4d.h:289
void Unmap()
Function Unmap() unmaps vertex buffer.
void EndDrawing() const
Function EndDrawing() finishes drawing operations.
static GPU_MANAGER * MakeManager(VERTEX_CONTAINER *aContainer)
Definition: gpu_manager.cpp:42
void Map()
Function Map() maps vertex buffer.
unsigned int GetOffset() const
Function GetOffset() Returns data offset in the container.
Definition: vertex_item.h:66
Class SHADER provides the access to the OpenGL shaders.
Definition: shader.h:74
void putVertex(VERTEX &aTarget, GLfloat aX, GLfloat aY, GLfloat aZ) const
Function putVertex() applies all transformation to the given coordinates and store them at the specif...
void BeginDrawing() const
Function BeginDrawing() prepares buffers and items to start drawing.
bool Vertices(const VERTEX aVertices[], unsigned int aSize)
Function Vertices() adds one or more vertices to the currently set item.
Class to store instances of VERTEX without caching.
void ChangeItemColor(const VERTEX_ITEM &aItem, const COLOR4D &aColor) const
Function ChangeItemColor() changes the color of all vertices owned by an item.
GLubyte m_color[COLOR_STRIDE]
Currently used color.
Class to handle an item held in a container.
void FinishItem() const
Function FinishItem() does the cleaning after adding an item.
VERTEX_MANAGER(bool aCached)
Constructor.
unsigned int GetSize() const
Function GetSize() Returns information about number of vertices stored.
Definition: vertex_item.h:56
static constexpr size_t SHADER_STRIDE
Definition: vertex_common.h:71
double r
Red component.
Definition: color4d.h:286
std::shared_ptr< GPU_MANAGER > m_gpu
GPU manager for data transfers and drawing operations.
void DrawItem(const VERTEX_ITEM &aItem) const
Function DrawItem() draws an item to the buffer.
VERTEX * m_reserved
Currently reserved chunk to store vertices.
void DisplayError(wxWindow *parent, const wxString &text, int displaytime)
Function DisplayError displays an error or warning message box with aMessage.
Definition: confirm.cpp:71
unsigned int m_reservedSpace
Currently available reserved space.
void SetShader(SHADER &aShader) const
Function SetShader() sets a shader program that is going to be used during rendering.
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39