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 (C) 2021, 2024 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, 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
38#include <confirm.h>
39#include <wx/log.h>
40
41
47static const wxChar traceVertexManager[] = wxT( "KICAD_VERTEX_MANAGER" );
48
49
50using namespace KIGFX;
51
53 m_noTransform( true ),
54 m_transform( 1.0f ),
55 m_reserved( nullptr ),
56 m_reservedSpace( 0 )
57{
60
61 // There is no shader used by default
62 for( unsigned int i = 0; i < SHADER_STRIDE; ++i )
63 m_shader[i] = 0.0f;
64}
65
66
68{
69 m_container->Map();
70}
71
72
74{
75 m_container->Unmap();
76}
77
78
79bool VERTEX_MANAGER::Reserve( unsigned int aSize )
80{
81 if( !aSize )
82 return true;
83
84 // flags to avoid hanging by calling DisplayError too many times:
85 static bool show_err_reserve = true;
86 static bool show_err_alloc = true;
87
88 if( m_reservedSpace != 0 || m_reserved )
89 {
90 if( show_err_reserve )
91 {
93 nullptr,
94 wxT( "VERTEX_MANAGER::Reserve: Did not use all previous vertices allocated" ) );
95
96 show_err_reserve = false;
97 }
98 }
99
100 m_reserved = m_container->Allocate( aSize );
101
102 if( m_reserved == nullptr )
103 {
104 if( show_err_alloc )
105 {
106 DisplayError( nullptr, wxT( "VERTEX_MANAGER::Reserve: Vertex allocation error" ) );
107 show_err_alloc = false;
108 }
109
110 return false;
111 }
112
113 m_reservedSpace = aSize;
114
115 return true;
116}
117
118
119bool VERTEX_MANAGER::Vertex( GLfloat aX, GLfloat aY, GLfloat aZ )
120{
121 // flag to avoid hanging by calling DisplayError too many times:
122 static bool show_err = true;
123
124 // Obtain the pointer to the vertex in the currently used container
125 VERTEX* newVertex;
126
127 if( m_reservedSpace > 0 )
128 {
129 newVertex = m_reserved++;
131
132 if( m_reservedSpace == 0 )
133 m_reserved = nullptr;
134 }
135 else
136 {
137 newVertex = m_container->Allocate( 1 );
138
139 if( newVertex == nullptr )
140 {
141 if( show_err )
142 {
143 DisplayError( nullptr, wxT( "VERTEX_MANAGER::Vertex: Vertex allocation error" ) );
144 show_err = false;
145 }
146
147 return false;
148 }
149 }
150
151 putVertex( *newVertex, aX, aY, aZ );
152
153 return true;
154}
155
156
157bool VERTEX_MANAGER::Vertices( const VERTEX aVertices[], unsigned int aSize )
158{
159 // flag to avoid hanging by calling DisplayError too many times:
160 static bool show_err = true;
161
162 // Obtain pointer to the vertex in currently used container
163 VERTEX* newVertex = m_container->Allocate( aSize );
164
165 if( newVertex == nullptr )
166 {
167 if( show_err )
168 {
169 DisplayError( nullptr, wxT( "VERTEX_MANAGER::Vertices: Vertex allocation error" ) );
170 show_err = false;
171 }
172
173 return false;
174 }
175
176 // Put vertices in already allocated memory chunk
177 for( unsigned int i = 0; i < aSize; ++i )
178 {
179 putVertex( newVertex[i], aVertices[i].x, aVertices[i].y, aVertices[i].z );
180 }
181
182 return true;
183}
184
185
187{
188 m_container->SetItem( &aItem );
189}
190
191
193{
194 if( m_reservedSpace != 0 || m_reserved )
195 wxLogTrace( traceVertexManager, wxS( "Did not use all previous vertices allocated" ) );
196
197 m_container->FinishItem();
198}
199
200
202{
203 m_container->Delete( &aItem );
204}
205
206
207void VERTEX_MANAGER::ChangeItemColor( const VERTEX_ITEM& aItem, const COLOR4D& aColor ) const
208{
209 unsigned int size = aItem.GetSize();
210 unsigned int offset = aItem.GetOffset();
211
212 VERTEX* vertex = m_container->GetVertices( offset );
213
214 for( unsigned int i = 0; i < size; ++i )
215 {
216 vertex->r = aColor.r * 255.0;
217 vertex->g = aColor.g * 255.0;
218 vertex->b = aColor.b * 255.0;
219 vertex->a = aColor.a * 255.0;
220 vertex++;
221 }
222
223 m_container->SetDirty();
224}
225
226
227void VERTEX_MANAGER::ChangeItemDepth( const VERTEX_ITEM& aItem, GLfloat aDepth ) const
228{
229 unsigned int size = aItem.GetSize();
230 unsigned int offset = aItem.GetOffset();
231
232 VERTEX* vertex = m_container->GetVertices( offset );
233
234 for( unsigned int i = 0; i < size; ++i )
235 {
236 vertex->z = aDepth;
237 vertex++;
238 }
239
240 m_container->SetDirty();
241}
242
243
245{
246 if( aItem.GetSize() == 0 )
247 return nullptr; // The item is not stored in the container
248
249 return m_container->GetVertices( aItem.GetOffset() );
250}
251
252
253void VERTEX_MANAGER::SetShader( SHADER& aShader ) const
254{
255 m_gpu->SetShader( aShader );
256}
257
258
260{
261 m_container->Clear();
262}
263
264
266{
267 m_gpu->BeginDrawing();
268}
269
270
271void VERTEX_MANAGER::DrawItem( const VERTEX_ITEM& aItem ) const
272{
273 m_gpu->DrawIndices( &aItem );
274}
275
276
278{
279 m_gpu->EndDrawing();
280}
281
282
283void VERTEX_MANAGER::putVertex( VERTEX& aTarget, GLfloat aX, GLfloat aY, GLfloat aZ ) const
284{
285 // Modify the vertex according to the currently used transformations
286 if( m_noTransform )
287 {
288 // Simply copy coordinates, when the transform matrix is the identity matrix
289 aTarget.x = aX;
290 aTarget.y = aY;
291 aTarget.z = aZ;
292 }
293 else
294 {
295 // Apply transformations
296 glm::vec4 transVertex( aX, aY, aZ, 1.0f );
297 transVertex = m_transform * transVertex;
298
299 aTarget.x = transVertex.x;
300 aTarget.y = transVertex.y;
301 aTarget.z = transVertex.z;
302 }
303
304 // Apply currently used color
305 aTarget.r = m_color[0];
306 aTarget.g = m_color[1];
307 aTarget.b = m_color[2];
308 aTarget.a = m_color[3];
309
310 // Apply currently used shader
311 for( unsigned int j = 0; j < SHADER_STRIDE; ++j )
312 {
313 aTarget.shader[j] = m_shader[j];
314 }
315}
316
317
319{
320 m_gpu->EnableDepthTest( aEnabled );
321}
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
double r
Red component.
Definition: color4d.h:392
double g
Green component.
Definition: color4d.h:393
double a
Alpha component.
Definition: color4d.h:395
double b
Blue component.
Definition: color4d.h:394
static GPU_MANAGER * MakeManager(VERTEX_CONTAINER *aContainer)
Definition: gpu_manager.cpp:48
Provide the access to the OpenGL shaders.
Definition: shader.h:77
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:68
unsigned int GetSize() const
Return information about number of vertices stored.
Definition: vertex_item.h:58
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 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, int aDisplayTime)
Display an error or warning message box with aMessage.
Definition: confirm.cpp:170
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: color4d.cpp:247
static constexpr size_t SHADER_STRIDE
Definition: vertex_common.h:81
Class to store instances of VERTEX without caching.
GLfloat shader[4]
Definition: vertex_common.h:64
Class to handle an item held in a container.