KiCad PCB EDA Suite
Loading...
Searching...
No Matches
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 The KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * @author Maciej Suminski <[email protected]>
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, see <https://www.gnu.org/licenses/>.
21 */
22
28
34#include <confirm.h>
35#include <wx/log.h>
36
37
43static const wxChar traceVertexManager[] = wxT( "KICAD_VERTEX_MANAGER" );
44
45
46using namespace KIGFX;
47
49 m_noTransform( true ),
50 m_transform( 1.0f ),
51 m_reserved( nullptr ),
53{
56
57 // There is no shader used by default
58 for( unsigned int i = 0; i < SHADER_STRIDE; ++i )
59 m_shader[i] = 0.0f;
60}
61
62
63VERTEX_MANAGER::VERTEX_MANAGER( std::shared_ptr<VERTEX_CONTAINER> aContainer ) :
64 m_container( std::move( aContainer ) ),
65 m_noTransform( true ),
66 m_transform( 1.0f ),
67 m_reserved( nullptr ),
69{
70 for( unsigned int i = 0; i < SHADER_STRIDE; ++i )
71 m_shader[i] = 0.0f;
72}
73
74
76{
77 m_container->Abandon();
78}
79
80
82{
83 m_container->Map();
84}
85
86
88{
89 m_container->Unmap();
90}
91
92
93bool VERTEX_MANAGER::Reserve( unsigned int aSize )
94{
95 if( !aSize )
96 return true;
97
98 // flags to avoid hanging by calling DisplayError too many times:
99 static bool show_err_reserve = true;
100 static bool show_err_alloc = true;
101
102 if( m_reservedSpace != 0 || m_reserved )
103 {
104 if( show_err_reserve )
105 {
106 DisplayError( nullptr, wxT( "VERTEX_MANAGER::Reserve: Did not use all previous vertices allocated" ) );
107 show_err_reserve = false;
108 }
109 }
110
111 m_reserved = m_container->Allocate( aSize );
112
113 if( m_reserved == nullptr )
114 {
115 if( show_err_alloc )
116 {
117 DisplayError( nullptr, wxT( "VERTEX_MANAGER::Reserve: Vertex allocation error" ) );
118 show_err_alloc = false;
119 }
120
121 return false;
122 }
123
124 m_reservedSpace = aSize;
125
126 return true;
127}
128
129
130bool VERTEX_MANAGER::Vertex( GLfloat aX, GLfloat aY, GLfloat aZ )
131{
132 // flag to avoid hanging by calling DisplayError too many times:
133 static bool show_err = true;
134
135 // Obtain the pointer to the vertex in the currently used container
136 VERTEX* newVertex;
137
138 if( m_reservedSpace > 0 )
139 {
140 newVertex = m_reserved++;
142
143 if( m_reservedSpace == 0 )
144 m_reserved = nullptr;
145 }
146 else
147 {
148 newVertex = m_container->Allocate( 1 );
149
150 if( newVertex == nullptr )
151 {
152 if( show_err )
153 {
154 DisplayError( nullptr, wxT( "VERTEX_MANAGER::Vertex: Vertex allocation error" ) );
155 show_err = false;
156 }
157
158 return false;
159 }
160 }
161
162 putVertex( *newVertex, aX, aY, aZ );
163
164 return true;
165}
166
167
168bool VERTEX_MANAGER::Vertices( const VERTEX aVertices[], unsigned int aSize )
169{
170 // flag to avoid hanging by calling DisplayError too many times:
171 static bool show_err = true;
172
173 // Obtain pointer to the vertex in currently used container
174 VERTEX* newVertex = m_container->Allocate( aSize );
175
176 if( newVertex == nullptr )
177 {
178 if( show_err )
179 {
180 DisplayError( nullptr, wxT( "VERTEX_MANAGER::Vertices: Vertex allocation error" ) );
181 show_err = false;
182 }
183
184 return false;
185 }
186
187 // Put vertices in already allocated memory chunk
188 for( unsigned int i = 0; i < aSize; ++i )
189 {
190 putVertex( newVertex[i], aVertices[i].x, aVertices[i].y, aVertices[i].z );
191 }
192
193 return true;
194}
195
196
198{
199 m_container->SetItem( &aItem );
200}
201
202
204{
205 if( m_reservedSpace != 0 || m_reserved )
206 wxLogTrace( traceVertexManager, wxS( "Did not use all previous vertices allocated" ) );
207
208 m_container->FinishItem();
209}
210
211
213{
214 m_container->Delete( &aItem );
215}
216
217
218void VERTEX_MANAGER::ChangeItemColor( const VERTEX_ITEM& aItem, const COLOR4D& aColor ) const
219{
220 unsigned int size = aItem.GetSize();
221 unsigned int offset = aItem.GetOffset();
222
223 VERTEX* vertex = m_container->GetVertices( offset );
224
225 for( unsigned int i = 0; i < size; ++i )
226 {
227 vertex->r = aColor.r * 255.0;
228 vertex->g = aColor.g * 255.0;
229 vertex->b = aColor.b * 255.0;
230 vertex->a = aColor.a * 255.0;
231 vertex++;
232 }
233
234 m_container->SetDirty();
235}
236
237
238void VERTEX_MANAGER::ChangeItemDepth( const VERTEX_ITEM& aItem, GLfloat aDepth ) const
239{
240 unsigned int size = aItem.GetSize();
241 unsigned int offset = aItem.GetOffset();
242
243 VERTEX* vertex = m_container->GetVertices( offset );
244
245 for( unsigned int i = 0; i < size; ++i )
246 {
247 vertex->z = aDepth;
248 vertex++;
249 }
250
251 m_container->SetDirty();
252}
253
254
256{
257 if( aItem.GetSize() == 0 )
258 return nullptr; // The item is not stored in the container
259
260 return m_container->GetVertices( aItem.GetOffset() );
261}
262
263
264void VERTEX_MANAGER::SetShader( SHADER& aShader ) const
265{
266 m_gpu->SetShader( aShader );
267}
268
269
271{
272 m_container->Clear();
273}
274
275
277{
278 m_gpu->BeginDrawing();
279}
280
281
282void VERTEX_MANAGER::DrawItem( const VERTEX_ITEM& aItem ) const
283{
284 m_gpu->DrawIndices( &aItem );
285}
286
287
289{
290 m_gpu->EndDrawing();
291}
292
293
294void VERTEX_MANAGER::putVertex( VERTEX& aTarget, GLfloat aX, GLfloat aY, GLfloat aZ ) const
295{
296 // Modify the vertex according to the currently used transformations
297 if( m_noTransform )
298 {
299 // Simply copy coordinates, when the transform matrix is the identity matrix
300 aTarget.x = aX;
301 aTarget.y = aY;
302 aTarget.z = aZ;
303 }
304 else
305 {
306 // Apply transformations
307 glm::vec4 transVertex( aX, aY, aZ, 1.0f );
308 transVertex = m_transform * transVertex;
309
310 aTarget.x = transVertex.x;
311 aTarget.y = transVertex.y;
312 aTarget.z = transVertex.z;
313 }
314
315 // Apply currently used color
316 aTarget.r = m_color[0];
317 aTarget.g = m_color[1];
318 aTarget.b = m_color[2];
319 aTarget.a = m_color[3];
320
321 // Apply currently used shader
322 for( unsigned int j = 0; j < SHADER_STRIDE; ++j )
323 {
324 aTarget.shader[j] = m_shader[j];
325 }
326}
327
328
330{
331 m_gpu->EnableDepthTest( aEnabled );
332}
A color representation with 4 components: red, green, blue, alpha.
Definition color4d.h:101
double r
Red component.
Definition color4d.h:391
double g
Green component.
Definition color4d.h:392
double a
Alpha component.
Definition color4d.h:394
double b
Blue component.
Definition color4d.h:393
static GPU_MANAGER * MakeManager(VERTEX_CONTAINER *aContainer)
Provide the access to the OpenGL shaders.
Definition shader.h:73
static VERTEX_CONTAINER * MakeContainer(bool aCached)
Return a pointer to a new container of an appropriate type.
unsigned int GetOffset() const
Return data offset in the container.
Definition vertex_item.h:65
unsigned int GetSize() const
Return information about number of vertices stored.
Definition vertex_item.h:55
void EndDrawing() const
Finish drawing operations.
bool Vertex(const VERTEX &aVertex)
Add a vertex with the given coordinates to the currently set item.
void Map()
Map vertex buffer.
bool m_noTransform
State machine variables True in case there is no need to transform vertices.
void SetItem(VERTEX_ITEM &aItem) const
Set an item to start its modifications.
void Clear() const
Remove all the stored vertices from the container.
void Abandon()
Give up ownership of the container's GL objects without deleting them.
void BeginDrawing() const
Prepare buffers and items to start drawing.
void ChangeItemColor(const VERTEX_ITEM &aItem, const COLOR4D &aColor) const
Change the color of all vertices owned by an item.
bool Reserve(unsigned int aSize)
Allocate space for vertices, so it will be used with subsequent Vertex() calls.
void FinishItem() const
Clean after adding an item.
void ChangeItemDepth(const VERTEX_ITEM &aItem, GLfloat aDepth) const
Change the depth of all vertices owned by an item.
void FreeItem(VERTEX_ITEM &aItem) const
Free the memory occupied by the item, so it is no longer stored in the container.
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.
void EnableDepthTest(bool aEnabled)
Enable/disable Z buffer depth test.
glm::mat4 m_transform
Currently used transform matrix.
VERTEX_MANAGER(bool aCached)
unsigned int m_reservedSpace
Currently available reserved space.
VERTEX * GetVertices(const VERTEX_ITEM &aItem) const
Return a pointer to the vertices owned by an item.
VERTEX * m_reserved
Currently reserved chunk to store vertices.
GLubyte m_color[COLOR_STRIDE]
Currently used color.
GLfloat m_shader[SHADER_STRIDE]
Currently used shader and its parameters.
void Unmap()
Unmap vertex buffer.
bool Vertices(const VERTEX aVertices[], unsigned int aSize)
Add one or more vertices to the currently set item.
void SetShader(SHADER &aShader) const
Set a shader program that is going to be used during rendering.
std::shared_ptr< GPU_MANAGER > m_gpu
GPU manager for data transfers and drawing operations.
std::shared_ptr< VERTEX_CONTAINER > m_container
Container for vertices, may be cached or noncached.
void DrawItem(const VERTEX_ITEM &aItem) const
Draw an item to the buffer.
void DisplayError(wxWindow *aParent, const wxString &aText)
Display an error or warning message box with aMessage.
Definition confirm.cpp:192
This file is part of the common library.
static const wxChar traceVertexManager[]
Flag to enable VERTEX_MANAGER debugging output.
The Cairo implementation of the graphics abstraction layer.
Definition eda_group.h:30
static constexpr size_t SHADER_STRIDE
STL namespace.
Class to store instances of VERTEX without caching.
GLfloat shader[4]
Class to handle an item held in a container.