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