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 <[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
40using namespace KIGFX;
41
42VERTEX_MANAGER::VERTEX_MANAGER( bool aCached ) :
43 m_noTransform( true ),
44 m_transform( 1.0f ),
45 m_reserved( nullptr ),
46 m_reservedSpace( 0 )
47{
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
69bool VERTEX_MANAGER::Reserve( unsigned int aSize )
70{
71 if( !aSize )
72 return true;
73
74 assert( m_reservedSpace == 0 && m_reserved == nullptr );
75
76 // flag to avoid hanging by calling DisplayError too many times:
77 static bool show_err = true;
78
79 m_reserved = m_container->Allocate( aSize );
80
81 if( m_reserved == nullptr )
82 {
83 if( show_err )
84 {
85 DisplayError( nullptr, wxT( "VERTEX_MANAGER::Reserve: Vertex allocation error" ) );
86 show_err = false;
87 }
88
89 return false;
90 }
91
92 m_reservedSpace = aSize;
93
94 return true;
95}
96
97
98bool VERTEX_MANAGER::Vertex( GLfloat aX, GLfloat aY, GLfloat aZ )
99{
100 // flag to avoid hanging by calling DisplayError too many times:
101 static bool show_err = true;
102
103 // Obtain the pointer to the vertex in the currently used container
104 VERTEX* newVertex;
105
106 if( m_reservedSpace > 0 )
107 {
108 newVertex = m_reserved++;
110
111 if( m_reservedSpace == 0 )
112 m_reserved = nullptr;
113 }
114 else
115 {
116 newVertex = m_container->Allocate( 1 );
117
118 if( newVertex == nullptr )
119 {
120 if( show_err )
121 {
122 DisplayError( nullptr, wxT( "VERTEX_MANAGER::Vertex: Vertex allocation error" ) );
123 show_err = false;
124 }
125
126 return false;
127 }
128 }
129
130 putVertex( *newVertex, aX, aY, aZ );
131
132 return true;
133}
134
135
136bool VERTEX_MANAGER::Vertices( const VERTEX aVertices[], unsigned int aSize )
137{
138 // flag to avoid hanging by calling DisplayError too many times:
139 static bool show_err = true;
140
141 // Obtain pointer to the vertex in currently used container
142 VERTEX* newVertex = m_container->Allocate( aSize );
143
144 if( newVertex == nullptr )
145 {
146 if( show_err )
147 {
148 DisplayError( nullptr, wxT( "VERTEX_MANAGER::Vertices: Vertex allocation error" ) );
149 show_err = false;
150 }
151
152 return false;
153 }
154
155 // Put vertices in already allocated memory chunk
156 for( unsigned int i = 0; i < aSize; ++i )
157 {
158 putVertex( newVertex[i], aVertices[i].x, aVertices[i].y, aVertices[i].z );
159 }
160
161 return true;
162}
163
164
166{
167 m_container->SetItem( &aItem );
168}
169
170
172{
173 assert( m_reservedSpace == 0 && m_reserved == nullptr );
174
175 m_container->FinishItem();
176}
177
178
180{
181 m_container->Delete( &aItem );
182}
183
184
185void VERTEX_MANAGER::ChangeItemColor( const VERTEX_ITEM& aItem, const COLOR4D& aColor ) const
186{
187 unsigned int size = aItem.GetSize();
188 unsigned int offset = aItem.GetOffset();
189
190 VERTEX* vertex = m_container->GetVertices( offset );
191
192 for( unsigned int i = 0; i < size; ++i )
193 {
194 vertex->r = aColor.r * 255.0;
195 vertex->g = aColor.g * 255.0;
196 vertex->b = aColor.b * 255.0;
197 vertex->a = aColor.a * 255.0;
198 vertex++;
199 }
200
201 m_container->SetDirty();
202}
203
204
205void VERTEX_MANAGER::ChangeItemDepth( const VERTEX_ITEM& aItem, GLfloat aDepth ) const
206{
207 unsigned int size = aItem.GetSize();
208 unsigned int offset = aItem.GetOffset();
209
210 VERTEX* vertex = m_container->GetVertices( offset );
211
212 for( unsigned int i = 0; i < size; ++i )
213 {
214 vertex->z = aDepth;
215 vertex++;
216 }
217
218 m_container->SetDirty();
219}
220
221
223{
224 if( aItem.GetSize() == 0 )
225 return nullptr; // The item is not stored in the container
226
227 return m_container->GetVertices( aItem.GetOffset() );
228}
229
230
231void VERTEX_MANAGER::SetShader( SHADER& aShader ) const
232{
233 m_gpu->SetShader( aShader );
234}
235
236
238{
239 m_container->Clear();
240}
241
242
244{
245 m_gpu->BeginDrawing();
246}
247
248
249void VERTEX_MANAGER::DrawItem( const VERTEX_ITEM& aItem ) const
250{
251 m_gpu->DrawIndices( &aItem );
252}
253
254
256{
257 m_gpu->EndDrawing();
258}
259
260
261void VERTEX_MANAGER::putVertex( VERTEX& aTarget, GLfloat aX, GLfloat aY, GLfloat aZ ) const
262{
263 // Modify the vertex according to the currently used transformations
264 if( m_noTransform )
265 {
266 // Simply copy coordinates, when the transform matrix is the identity matrix
267 aTarget.x = aX;
268 aTarget.y = aY;
269 aTarget.z = aZ;
270 }
271 else
272 {
273 // Apply transformations
274 glm::vec4 transVertex( aX, aY, aZ, 1.0f );
275 transVertex = m_transform * transVertex;
276
277 aTarget.x = transVertex.x;
278 aTarget.y = transVertex.y;
279 aTarget.z = transVertex.z;
280 }
281
282 // Apply currently used color
283 aTarget.r = m_color[0];
284 aTarget.g = m_color[1];
285 aTarget.b = m_color[2];
286 aTarget.a = m_color[3];
287
288 // Apply currently used shader
289 for( unsigned int j = 0; j < SHADER_STRIDE; ++j )
290 {
291 aTarget.shader[j] = m_shader[j];
292 }
293}
294
296{
297 m_gpu->EnableDepthTest( aEnabled );
298}
A color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:104
double r
Red component.
Definition: color4d.h:384
double g
Green component.
Definition: color4d.h:385
double a
Alpha component.
Definition: color4d.h:387
double b
Blue component.
Definition: color4d.h:386
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.
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:280
This file is part of the common library.
The Cairo implementation of the graphics abstraction layer.
Definition: color4d.cpp:266
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.