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, see <https://www.gnu.org/licenses/>.
20 */
21
22#include <kicad_gl/kiglad.h> // Must be included first
23
24#include <algorithm>
25#include <atomic>
26#include <chrono>
27#include <thread>
28
29#include <wx/log.h>
30
32#include "../common_ogl/ogl_utils.h"
33
34#include <core/profile.h> // To use GetRunningMicroSecs or another profiling utility
35#include <eda_3d_canvas.h>
36
37
39 CAMERA& aCamera ) :
40 RENDER_3D_RAYTRACE_BASE( aAdapter, aCamera )
41{
42 wxLogTrace( m_logTrace, wxT( "RENDER_3D_RAYTRACE_GL::RENDER_3D_RAYTRACE_GL" ) );
43
45 m_pboId = GL_NONE;
46 m_pboDataSize = 0;
47}
48
49
54
55
57{
58 // Delete PBO if it was created
60 {
61 if( glIsBuffer( m_pboId ) )
62 glDeleteBuffers( 1, &m_pboId );
63
64 m_pboId = GL_NONE;
65 }
66}
67
68
69void RENDER_3D_RAYTRACE_GL::SetCurWindowSize( const wxSize& aSize )
70{
71 if( m_windowSize != aSize )
72 {
73 m_windowSize = aSize;
74 glViewport( 0, 0, m_windowSize.x, m_windowSize.y );
75
76 initPbo();
77 }
78}
79
80
81bool RENDER_3D_RAYTRACE_GL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
82 REPORTER* aWarningReporter )
83{
84 bool requestRedraw = false;
85
86 // Initialize openGL if need
88 {
90
91 //aIsMoving = true;
92 requestRedraw = true;
93
94 // It will assign the first time the windows size, so it will now
95 // revert to preview mode the first time the Redraw is called
98 }
99
100 std::unique_ptr<BUSY_INDICATOR> busy = CreateBusyIndicator();
101
102 // Reload board if it was requested
104 {
105 if( aStatusReporter )
106 aStatusReporter->Report( _( "Loading..." ) );
107
108 //aIsMoving = true;
109 requestRedraw = true;
110 Reload( aStatusReporter, aWarningReporter, false );
111 }
112
113
114 // Recalculate constants if windows size was changed
116 {
118 aIsMoving = true;
119 requestRedraw = true;
120
122 }
123
124 // Clear buffers
125 glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
126 glClearDepth( 1.0f );
127 glClearStencil( 0x00 );
128 glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
129
130 // 4-byte pixel alignment
131 glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
132
133 glDisable( GL_STENCIL_TEST );
134 glDisable( GL_LIGHTING );
135 glDisable( GL_COLOR_MATERIAL );
136 glDisable( GL_DEPTH_TEST );
137 glDisable( GL_TEXTURE_2D );
138 glDisable( GL_BLEND );
139 glDisable( GL_MULTISAMPLE );
140
141 const bool was_camera_changed = m_camera.ParametersChanged();
142
143 if( requestRedraw || aIsMoving || was_camera_changed )
144 m_renderState = RT_RENDER_STATE_MAX; // Set to an invalid state,
145 // so it will restart again latter
146
147 // This will only render if need, otherwise it will redraw the PBO on the screen again
148 if( aIsMoving || was_camera_changed )
149 {
150 // Set head light (camera view light) with the opposite direction of the camera
151 if( m_cameraLight )
152 m_cameraLight->SetDirection( -m_camera.GetDir() );
153
155 premultiplyAlpha( m_boardAdapter.m_BgColorBot ) );
156
157 // Bind PBO
158 glBindBuffer( GL_PIXEL_UNPACK_BUFFER, m_pboId );
159
160 // Get the PBO pixel pointer to write the data
161 uint8_t* ptrPBO = (uint8_t *)glMapBuffer( GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY );
162
163 if( ptrPBO )
164 {
165 renderPreview( ptrPBO );
166
167 // release pointer to mapping buffer, this initialize the coping to PBO
168 glUnmapBuffer( GL_PIXEL_UNPACK_BUFFER );
169 }
170
171 glWindowPos2i( m_xoffset, m_yoffset );
172 }
173 else
174 {
175 // Bind PBO
176 glBindBuffer( GL_PIXEL_UNPACK_BUFFER, m_pboId );
177
179 {
180 // Get the PBO pixel pointer to write the data
181 uint8_t* ptrPBO = (uint8_t *)glMapBuffer( GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY );
182
183 if( ptrPBO )
184 {
185 render( ptrPBO, aStatusReporter );
186
188 requestRedraw = true;
189
190 // release pointer to mapping buffer, this initialize the coping to PBO
191 glUnmapBuffer( GL_PIXEL_UNPACK_BUFFER );
192 }
193 }
194
196 {
197 glClear( GL_COLOR_BUFFER_BIT );
198 }
199
200 glWindowPos2i( m_xoffset, m_yoffset );
201 }
202
203 // This way it will blend the progress rendering with the last buffer. eg:
204 // if it was called after a openGL.
205 glEnable( GL_BLEND );
206 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
207 glEnable( GL_ALPHA_TEST );
208 glDrawPixels( m_realBufferSize.x, m_realBufferSize.y, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
209 glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0 );
210
211 return requestRedraw;
212}
213
214
216{
217 if( GLAD_GL_VERSION_1_5 )
218 {
220
221 // Try to delete vbo if it was already initialized
222 deletePbo();
223
224 // Learn about Pixel buffer objects at:
225 // http://www.songho.ca/opengl/gl_pbo.html
226 // http://web.eecs.umich.edu/~sugih/courses/eecs487/lectures/25-PBO+Mipmapping.pdf
227 // "create 2 pixel buffer objects, you need to delete them when program exits.
228 // glBufferData with NULL pointer reserves only memory space."
229
230 // This sets the number of RGBA pixels
232
233 glGenBuffers( 1, &m_pboId );
234 glBindBuffer( GL_PIXEL_UNPACK_BUFFER, m_pboId );
235 glBufferData( GL_PIXEL_UNPACK_BUFFER, m_pboDataSize, 0, GL_STREAM_DRAW );
236 glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0 );
237
238 wxLogTrace( m_logTrace,
239 wxT( "RENDER_3D_RAYTRACE_GL:: GL Version 1.5+ is supported" ) );
240 }
241}
Helper class to handle information needed to display 3D board.
A class used to derive camera objects from.
Definition camera.h:99
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:71
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Definition reporter.h:100
#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