KiCad PCB EDA Suite
Loading...
Searching...
No Matches
render_3d_raytrace_gl.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) 2015-2020 Mario Luzeiro <[email protected]>
5 * Copyright (C) 2024 Alex Shvartzkop <[email protected]>
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU General Public License
10 * as published by the Free Software Foundation; either version 2
11 * of the License, or (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, you may find one here:
20 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
21 * or you may search the http://www.gnu.org website for the version 2 license,
22 * or you may write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
24 */
25
26#include <kicad_gl/kiglad.h> // Must be included first
27
28#include <algorithm>
29#include <atomic>
30#include <chrono>
31#include <thread>
32
33#include <wx/log.h>
34
36#include "../common_ogl/ogl_utils.h"
37
38#include <core/profile.h> // To use GetRunningMicroSecs or another profiling utility
39#include <eda_3d_canvas.h>
40
41
43 CAMERA& aCamera ) :
44 RENDER_3D_RAYTRACE_BASE( aAdapter, aCamera )
45{
46 wxLogTrace( m_logTrace, wxT( "RENDER_3D_RAYTRACE_GL::RENDER_3D_RAYTRACE_GL" ) );
47
49 m_pboId = GL_NONE;
50 m_pboDataSize = 0;
51}
52
53
58
59
61{
62 // Delete PBO if it was created
64 {
65 if( glIsBuffer( m_pboId ) )
66 glDeleteBuffers( 1, &m_pboId );
67
68 m_pboId = GL_NONE;
69 }
70}
71
72
73void RENDER_3D_RAYTRACE_GL::SetCurWindowSize( const wxSize& aSize )
74{
75 if( m_windowSize != aSize )
76 {
77 m_windowSize = aSize;
78 glViewport( 0, 0, m_windowSize.x, m_windowSize.y );
79
80 initPbo();
81 }
82}
83
84
85bool RENDER_3D_RAYTRACE_GL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
86 REPORTER* aWarningReporter )
87{
88 bool requestRedraw = false;
89
90 // Initialize openGL if need
92 {
94
95 //aIsMoving = true;
96 requestRedraw = true;
97
98 // It will assign the first time the windows size, so it will now
99 // revert to preview mode the first time the Redraw is called
102 }
103
104 std::unique_ptr<BUSY_INDICATOR> busy = CreateBusyIndicator();
105
106 // Reload board if it was requested
108 {
109 if( aStatusReporter )
110 aStatusReporter->Report( _( "Loading..." ) );
111
112 //aIsMoving = true;
113 requestRedraw = true;
114 Reload( aStatusReporter, aWarningReporter, false );
115 }
116
117
118 // Recalculate constants if windows size was changed
120 {
122 aIsMoving = true;
123 requestRedraw = true;
124
126 }
127
128 // Clear buffers
129 glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
130 glClearDepth( 1.0f );
131 glClearStencil( 0x00 );
132 glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
133
134 // 4-byte pixel alignment
135 glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
136
137 glDisable( GL_STENCIL_TEST );
138 glDisable( GL_LIGHTING );
139 glDisable( GL_COLOR_MATERIAL );
140 glDisable( GL_DEPTH_TEST );
141 glDisable( GL_TEXTURE_2D );
142 glDisable( GL_BLEND );
143 glDisable( GL_MULTISAMPLE );
144
145 const bool was_camera_changed = m_camera.ParametersChanged();
146
147 if( requestRedraw || aIsMoving || was_camera_changed )
148 m_renderState = RT_RENDER_STATE_MAX; // Set to an invalid state,
149 // so it will restart again latter
150
151 // This will only render if need, otherwise it will redraw the PBO on the screen again
152 if( aIsMoving || was_camera_changed )
153 {
154 // Set head light (camera view light) with the opposite direction of the camera
155 if( m_cameraLight )
156 m_cameraLight->SetDirection( -m_camera.GetDir() );
157
159 premultiplyAlpha( m_boardAdapter.m_BgColorBot ) );
160
161 // Bind PBO
162 glBindBuffer( GL_PIXEL_UNPACK_BUFFER, m_pboId );
163
164 // Get the PBO pixel pointer to write the data
165 uint8_t* ptrPBO = (uint8_t *)glMapBuffer( GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY );
166
167 if( ptrPBO )
168 {
169 renderPreview( ptrPBO );
170
171 // release pointer to mapping buffer, this initialize the coping to PBO
172 glUnmapBuffer( GL_PIXEL_UNPACK_BUFFER );
173 }
174
175 glWindowPos2i( m_xoffset, m_yoffset );
176 }
177 else
178 {
179 // Bind PBO
180 glBindBuffer( GL_PIXEL_UNPACK_BUFFER, m_pboId );
181
183 {
184 // Get the PBO pixel pointer to write the data
185 uint8_t* ptrPBO = (uint8_t *)glMapBuffer( GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY );
186
187 if( ptrPBO )
188 {
189 render( ptrPBO, aStatusReporter );
190
192 requestRedraw = true;
193
194 // release pointer to mapping buffer, this initialize the coping to PBO
195 glUnmapBuffer( GL_PIXEL_UNPACK_BUFFER );
196 }
197 }
198
200 {
201 glClear( GL_COLOR_BUFFER_BIT );
202 }
203
204 glWindowPos2i( m_xoffset, m_yoffset );
205 }
206
207 // This way it will blend the progress rendering with the last buffer. eg:
208 // if it was called after a openGL.
209 glEnable( GL_BLEND );
210 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
211 glEnable( GL_ALPHA_TEST );
212 glDrawPixels( m_realBufferSize.x, m_realBufferSize.y, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
213 glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0 );
214
215 return requestRedraw;
216}
217
218
220{
221 if( GLAD_GL_VERSION_1_5 )
222 {
224
225 // Try to delete vbo if it was already initialized
226 deletePbo();
227
228 // Learn about Pixel buffer objects at:
229 // http://www.songho.ca/opengl/gl_pbo.html
230 // http://web.eecs.umich.edu/~sugih/courses/eecs487/lectures/25-PBO+Mipmapping.pdf
231 // "create 2 pixel buffer objects, you need to delete them when program exits.
232 // glBufferData with NULL pointer reserves only memory space."
233
234 // This sets the number of RGBA pixels
236
237 glGenBuffers( 1, &m_pboId );
238 glBindBuffer( GL_PIXEL_UNPACK_BUFFER, m_pboId );
239 glBufferData( GL_PIXEL_UNPACK_BUFFER, m_pboDataSize, 0, GL_STREAM_DRAW );
240 glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0 );
241
242 wxLogTrace( m_logTrace,
243 wxT( "RENDER_3D_RAYTRACE_GL:: GL Version 1.5+ is supported" ) );
244 }
245}
Helper class to handle information needed to display 3D board.
A class used to derive camera objects from.
Definition camera.h:103
Implement a canvas based on a wxGLCanvas.
std::unique_ptr< BUSY_INDICATOR > CreateBusyIndicator() const
Return a created busy indicator, if a factory has been set, else a null pointer.
bool m_canvasInitialized
Flag if the canvas specific for this render was already initialized.
wxSize m_windowSize
The window size that this camera is working.
BOARD_ADAPTER & m_boardAdapter
Settings reference in use for this render.
static SFVEC4F premultiplyAlpha(const SFVEC4F &aInput)
void Reload(REPORTER *aStatusReporter, REPORTER *aWarningReporter, bool aOnlyLoadCopperAndShapes)
RENDER_3D_RAYTRACE_BASE(BOARD_ADAPTER &aAdapter, CAMERA &aCamera)
void render(uint8_t *ptrPBO, REPORTER *aStatusReporter)
RT_RENDER_STATE m_renderState
State used on quality render.
wxSize m_oldWindowsSize
Used to see if the windows size changed.
void renderPreview(uint8_t *ptrPBO)
RENDER_3D_RAYTRACE_GL(EDA_3D_CANVAS *aCanvas, BOARD_ADAPTER &aAdapter, CAMERA &aCamera)
bool Redraw(bool aIsMoving, REPORTER *aStatusReporter, REPORTER *aWarningReporter) override
Redraw the view.
void SetCurWindowSize(const wxSize &aSize) override
Before each render, the canvas will tell the render what is the size of its windows,...
A pure virtual class used to derive REPORTER objects from.
Definition reporter.h:73
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Definition reporter.h:102
#define _(s)
static const wxChar * m_logTrace
Trace mask used to enable or disable the trace output of this class.
void OglDrawBackground(const SFVEC4F &aTopColor, const SFVEC4F &aBotColor)
@ RT_RENDER_STATE_FINISH
@ RT_RENDER_STATE_MAX