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