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