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