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 )
82{
83 bool requestRedraw = false;
84
85 // Initialize openGL if need
87 {
89
90 //aIsMoving = true;
91 requestRedraw = true;
92
93 // It will assign the first time the windows size, so it will now
94 // revert to preview mode the first time the Redraw is called
97 }
98
99 std::unique_ptr<BUSY_INDICATOR> busy = CreateBusyIndicator();
100
101 // Reload board if it was requested
103 {
105 m_activityReporter->Report( _( "Loading..." ) );
106
107 //aIsMoving = true;
108 requestRedraw = true;
109 Reload( false );
110 }
111
112
113 // Recalculate constants if windows size was changed
115 {
117 aIsMoving = true;
118 requestRedraw = true;
119
121 }
122
123 // Clear buffers
124 glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
125 glClearDepth( 1.0f );
126 glClearStencil( 0x00 );
127 glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
128
129 // 4-byte pixel alignment
130 glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
131
132 glDisable( GL_STENCIL_TEST );
133 glDisable( GL_LIGHTING );
134 glDisable( GL_COLOR_MATERIAL );
135 glDisable( GL_DEPTH_TEST );
136 glDisable( GL_TEXTURE_2D );
137 glDisable( GL_BLEND );
138 glDisable( GL_MULTISAMPLE );
139
140 const bool was_camera_changed = m_camera.ParametersChanged();
141
142 if( requestRedraw || aIsMoving || was_camera_changed )
143 m_renderState = RT_RENDER_STATE_MAX; // Set to an invalid state,
144 // so it will restart again latter
145
146 // This will only render if need, otherwise it will redraw the PBO on the screen again
147 if( aIsMoving || was_camera_changed )
148 {
149 // Set head light (camera view light) with the opposite direction of the camera
150 if( m_cameraLight )
151 m_cameraLight->SetDirection( -m_camera.GetDir() );
152
154 premultiplyAlpha( m_boardAdapter.m_BgColorBot ) );
155
156 // Bind PBO
157 glBindBuffer( GL_PIXEL_UNPACK_BUFFER, m_pboId );
158
159 // Get the PBO pixel pointer to write the data
160 uint8_t* ptrPBO = (uint8_t *)glMapBuffer( GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY );
161
162 if( ptrPBO )
163 {
164 renderPreview( ptrPBO );
165
166 // release pointer to mapping buffer, this initialize the coping to PBO
167 glUnmapBuffer( GL_PIXEL_UNPACK_BUFFER );
168 }
169
170 glWindowPos2i( m_xoffset, m_yoffset );
171 }
172 else
173 {
174 // Bind PBO
175 glBindBuffer( GL_PIXEL_UNPACK_BUFFER, m_pboId );
176
178 {
179 // Get the PBO pixel pointer to write the data
180 uint8_t* ptrPBO = (uint8_t *)glMapBuffer( GL_PIXEL_UNPACK_BUFFER, GL_WRITE_ONLY );
181
182 if( ptrPBO )
183 {
184 render( ptrPBO );
185
187 requestRedraw = true;
188
189 // release pointer to mapping buffer, this initialize the coping to PBO
190 glUnmapBuffer( GL_PIXEL_UNPACK_BUFFER );
191 }
192 }
193
195 {
196 glClear( GL_COLOR_BUFFER_BIT );
197 }
198
199 glWindowPos2i( m_xoffset, m_yoffset );
200 }
201
202 // This way it will blend the progress rendering with the last buffer. eg:
203 // if it was called after a openGL.
204 glEnable( GL_BLEND );
205 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
206 glEnable( GL_ALPHA_TEST );
207 glDrawPixels( m_realBufferSize.x, m_realBufferSize.y, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
208 glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0 );
209
210 return requestRedraw;
211}
212
213
215{
216 if( GLAD_GL_VERSION_1_5 )
217 {
219
220 // Try to delete vbo if it was already initialized
221 deletePbo();
222
223 // Learn about Pixel buffer objects at:
224 // http://www.songho.ca/opengl/gl_pbo.html
225 // http://web.eecs.umich.edu/~sugih/courses/eecs487/lectures/25-PBO+Mipmapping.pdf
226 // "create 2 pixel buffer objects, you need to delete them when program exits.
227 // glBufferData with NULL pointer reserves only memory space."
228
229 // This sets the number of RGBA pixels
231
232 glGenBuffers( 1, &m_pboId );
233 glBindBuffer( GL_PIXEL_UNPACK_BUFFER, m_pboId );
234 glBufferData( GL_PIXEL_UNPACK_BUFFER, m_pboDataSize, 0, GL_STREAM_DRAW );
235 glBindBuffer( GL_PIXEL_UNPACK_BUFFER, 0 );
236
237 wxLogTrace( m_logTrace,
238 wxT( "RENDER_3D_RAYTRACE_GL:: GL Version 1.5+ is supported" ) );
239 }
240}
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.
std::shared_ptr< REPORTER > m_activityReporter
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)
RENDER_3D_RAYTRACE_BASE(BOARD_ADAPTER &aAdapter, CAMERA &aCamera)
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)
void Reload(bool aOnlyLoadCopperAndShapes, std::stop_token aStop={})
RENDER_3D_RAYTRACE_GL(EDA_3D_CANVAS *aCanvas, BOARD_ADAPTER &aAdapter, CAMERA &aCamera)
bool Redraw(bool aIsMoving) 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,...
#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