mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-04-07 22:05:32 +00:00
ADDED: PCB 3D image raytracing rendering from CLI.
Fixes https://gitlab.com/kicad/code/kicad/-/issues/3691
This commit is contained in:
parent
7721bdc441
commit
f6f0b9a661
3d-viewer
3d_canvas
3d_rendering
opengl
raytracing
create_scene.cpprender_3d_raytrace_base.cpprender_3d_raytrace_base.hrender_3d_raytrace_gl.cpprender_3d_raytrace_gl.hrender_3d_raytrace_ram.cpprender_3d_raytrace_ram.h
render_3d_base.cpprender_3d_base.htrack_ball.cpptrack_ball.h3d_viewer
CMakeLists.txtcommon
include
kicad
pcbnew
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -32,7 +32,7 @@
|
||||
#include "../3d_rendering/raytracing/accelerators/container_3d.h"
|
||||
#include "../3d_rendering/raytracing/shapes3D/bbox_3d.h"
|
||||
#include <gal/3d/camera.h>
|
||||
#include "../3d_enums.h"
|
||||
#include <3d_enums.h>
|
||||
#include "../3d_cache/3d_cache.h"
|
||||
#include "../common_ogl/ogl_attr_list.h"
|
||||
#include "../3d_viewer/eda_3d_viewer_settings.h"
|
||||
|
@ -29,7 +29,7 @@
|
||||
#include "../common_ogl/ogl_utils.h"
|
||||
#include "eda_3d_canvas.h"
|
||||
#include <eda_3d_viewer_frame.h>
|
||||
#include <3d_rendering/raytracing/render_3d_raytrace.h>
|
||||
#include <3d_rendering/raytracing/render_3d_raytrace_gl.h>
|
||||
#include <3d_rendering/opengl/render_3d_opengl.h>
|
||||
#include <3d_viewer_id.h>
|
||||
#include <advanced_config.h>
|
||||
@ -119,7 +119,7 @@ EDA_3D_CANVAS::EDA_3D_CANVAS( wxWindow* aParent, const wxGLAttributes& aGLAttrib
|
||||
|
||||
m_is_currently_painting.clear();
|
||||
|
||||
m_3d_render_raytracing = new RENDER_3D_RAYTRACE( this, m_boardAdapter, m_camera );
|
||||
m_3d_render_raytracing = new RENDER_3D_RAYTRACE_GL( this, m_boardAdapter, m_camera );
|
||||
m_3d_render_opengl = new RENDER_3D_OPENGL( this, m_boardAdapter, m_camera );
|
||||
|
||||
wxASSERT( m_3d_render_raytracing != nullptr );
|
||||
@ -979,66 +979,24 @@ bool EDA_3D_CANVAS::SetView3D( VIEW3D_TYPE aRequestedView )
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_RIGHT:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Reset_T1();
|
||||
m_camera.RotateZ_T1( glm::radians( -90.0f ) );
|
||||
m_camera.RotateX_T1( glm::radians( -90.0f ) );
|
||||
request_start_moving_camera();
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_LEFT:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Reset_T1();
|
||||
m_camera.RotateZ_T1( glm::radians( 90.0f ) );
|
||||
m_camera.RotateX_T1( glm::radians( -90.0f ) );
|
||||
request_start_moving_camera();
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_FRONT:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Reset_T1();
|
||||
m_camera.RotateX_T1( glm::radians( -90.0f ) );
|
||||
request_start_moving_camera();
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_BACK:
|
||||
case VIEW3D_TYPE::VIEW3D_FLIP:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Reset_T1();
|
||||
m_camera.RotateX_T1( glm::radians( -90.0f ) );
|
||||
|
||||
// The rotation angle should be 180.
|
||||
// We use 179.999 (180 - epsilon) to avoid a full 360 deg rotation when
|
||||
// using 180 deg if the previous rotated position was already 180 deg
|
||||
m_camera.RotateZ_T1( glm::radians( 179.999f ) );
|
||||
m_camera.ViewCommand_T1( aRequestedView );
|
||||
request_start_moving_camera();
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_TOP:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Reset_T1();
|
||||
request_start_moving_camera( glm::min( glm::max( m_camera.GetZoom(), 0.5f ), 1.125f ) );
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_BOTTOM:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.Reset_T1();
|
||||
m_camera.RotateY_T1( glm::radians( 179.999f ) ); // Rotation = 180 - epsilon
|
||||
m_camera.ViewCommand_T1( aRequestedView );
|
||||
request_start_moving_camera( glm::min( glm::max( m_camera.GetZoom(), 0.5f ), 1.125f ) );
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_FLIP:
|
||||
m_camera.SetInterpolateMode( CAMERA_INTERPOLATION::BEZIER );
|
||||
m_camera.SetT0_and_T1_current_T();
|
||||
m_camera.RotateY_T1( glm::radians( 179.999f ) );
|
||||
request_start_moving_camera();
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -38,7 +38,7 @@
|
||||
class WX_INFOBAR;
|
||||
class wxStatusBar;
|
||||
class BOARD;
|
||||
class RENDER_3D_RAYTRACE;
|
||||
class RENDER_3D_RAYTRACE_GL;
|
||||
class RENDER_3D_OPENGL;
|
||||
|
||||
|
||||
@ -97,7 +97,7 @@ public:
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the current render ( a RENDER_3D_RAYTRACE* or a RENDER_3D_OPENGL* render )
|
||||
* @return the current render ( a RENDER_3D_RAYTRACE_GL* or a RENDER_3D_OPENGL* render )
|
||||
*/
|
||||
RENDER_3D_BASE* GetCurrentRender() const { return m_3d_render; }
|
||||
|
||||
@ -311,7 +311,7 @@ private:
|
||||
|
||||
BOARD_ADAPTER& m_boardAdapter; // Pre-computed 3D info and settings
|
||||
RENDER_3D_BASE* m_3d_render;
|
||||
RENDER_3D_RAYTRACE* m_3d_render_raytracing;
|
||||
RENDER_3D_RAYTRACE_GL* m_3d_render_raytracing;
|
||||
RENDER_3D_OPENGL* m_3d_render_opengl;
|
||||
|
||||
bool m_opengl_supports_raytracing;
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2020 Oleg Endo <olegendo@gcc.gnu.org>
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -30,7 +30,7 @@
|
||||
#include <plugins/3dapi/c3dmodel.h>
|
||||
#include "../../common_ogl/openGL_includes.h"
|
||||
#include "../raytracing/shapes3D/bbox_3d.h"
|
||||
#include "../../3d_enums.h"
|
||||
#include <3d_enums.h>
|
||||
|
||||
#include <wx/chartype.h>
|
||||
|
||||
|
@ -47,7 +47,8 @@
|
||||
|
||||
RENDER_3D_OPENGL::RENDER_3D_OPENGL( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdapter,
|
||||
CAMERA& aCamera ) :
|
||||
RENDER_3D_BASE( aCanvas, aAdapter, aCamera )
|
||||
RENDER_3D_BASE( aAdapter, aCamera ),
|
||||
m_canvas( aCanvas )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "RENDER_3D_OPENGL::RENDER_3D_OPENGL" ) );
|
||||
|
||||
@ -454,7 +455,7 @@ bool RENDER_3D_OPENGL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
|
||||
REPORTER* aWarningReporter )
|
||||
{
|
||||
// Initialize OpenGL
|
||||
if( !m_is_opengl_initialized )
|
||||
if( !m_canvasInitialized )
|
||||
{
|
||||
if( !initializeOpenGL() )
|
||||
return false;
|
||||
@ -823,7 +824,7 @@ bool RENDER_3D_OPENGL::initializeOpenGL()
|
||||
|
||||
// Use this mode if you want see the triangle lines (debug proposes)
|
||||
//glPolygonMode( GL_FRONT_AND_BACK, GL_LINE );
|
||||
m_is_opengl_initialized = true;
|
||||
m_canvasInitialized = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -1021,7 +1022,7 @@ void RENDER_3D_OPENGL::get3dModelsFromFootprint( std::list<MODELTORENDER> &aDstR
|
||||
const SFVEC3F offset = SFVEC3F( sM.m_Offset.x, sM.m_Offset.y, sM.m_Offset.z );
|
||||
const SFVEC3F rotation = SFVEC3F( sM.m_Rotation.x, sM.m_Rotation.y, sM.m_Rotation.z );
|
||||
const SFVEC3F scale = SFVEC3F( sM.m_Scale.x, sM.m_Scale.y, sM.m_Scale.z );
|
||||
|
||||
|
||||
std::vector<float> key = { offset.x, offset.y, offset.z,
|
||||
rotation.x, rotation.y, rotation.z,
|
||||
scale.x, scale.y, scale.z };
|
||||
@ -1134,7 +1135,7 @@ void RENDER_3D_OPENGL::renderTransparentModels( const glm::mat4 &aCameraViewMatr
|
||||
const SFVEC3F bBoxWorld = mtr.m_modelWorldMat * glm::vec4( bBoxCenter, 1.0f );
|
||||
|
||||
const float distanceToCamera = glm::length( cameraPos - bBoxWorld );
|
||||
|
||||
|
||||
transparentModelList.emplace_back( &mtr, distanceToCamera );
|
||||
}
|
||||
|
||||
@ -1224,7 +1225,7 @@ void RENDER_3D_OPENGL::renderModel( const glm::mat4 &aCameraViewMatrix,
|
||||
aModelToRender.m_model->DrawBbox();
|
||||
|
||||
glEnable( GL_LIGHTING );
|
||||
|
||||
|
||||
if( !wasBlendEnabled )
|
||||
glDisable( GL_BLEND );
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2015-2021 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -208,6 +208,8 @@ private:
|
||||
SMATERIAL m_GrayMaterial;
|
||||
} m_materials;
|
||||
|
||||
EDA_3D_CANVAS* m_canvas;
|
||||
|
||||
MAP_OGL_DISP_LISTS m_layers;
|
||||
OPENGL_RENDER_LIST* m_platedPadsFront;
|
||||
OPENGL_RENDER_LIST* m_platedPadsBack;
|
||||
|
@ -23,7 +23,7 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "render_3d_raytrace.h"
|
||||
#include "render_3d_raytrace_base.h"
|
||||
#include "shapes3D/plane_3d.h"
|
||||
#include "shapes3D/round_segment_3d.h"
|
||||
#include "shapes3D/layer_item_3d.h"
|
||||
@ -72,7 +72,7 @@ static float TransparencyControl( float aGrayColorValue, float aTransparency )
|
||||
#define UNITS3D_TO_UNITSPCB ( pcbIUScale.IU_PER_MM )
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::setupMaterials()
|
||||
void RENDER_3D_RAYTRACE_BASE::setupMaterials()
|
||||
{
|
||||
MATERIAL::SetDefaultRefractionRayCount( m_boardAdapter.m_Cfg->m_Render.raytrace_nrsamples_refractions );
|
||||
MATERIAL::SetDefaultReflectionRayCount( m_boardAdapter.m_Cfg->m_Render.raytrace_nrsamples_reflections );
|
||||
@ -176,7 +176,7 @@ void RENDER_3D_RAYTRACE::setupMaterials()
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::createObject( CONTAINER_3D& aDstContainer, const OBJECT_2D* aObject2D,
|
||||
void RENDER_3D_RAYTRACE_BASE::createObject( CONTAINER_3D& aDstContainer, const OBJECT_2D* aObject2D,
|
||||
float aZMin, float aZMax, const MATERIAL* aMaterial,
|
||||
const SFVEC3F& aObjColor )
|
||||
{
|
||||
@ -227,7 +227,7 @@ void RENDER_3D_RAYTRACE::createObject( CONTAINER_3D& aDstContainer, const OBJECT
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::createItemsFromContainer( const BVH_CONTAINER_2D* aContainer2d,
|
||||
void RENDER_3D_RAYTRACE_BASE::createItemsFromContainer( const BVH_CONTAINER_2D* aContainer2d,
|
||||
PCB_LAYER_ID aLayer_id,
|
||||
const MATERIAL* aMaterialLayer,
|
||||
const SFVEC3F& aLayerColor,
|
||||
@ -358,7 +358,7 @@ void RENDER_3D_RAYTRACE::createItemsFromContainer( const BVH_CONTAINER_2D* aCont
|
||||
extern void buildBoardBoundingBoxPoly( const BOARD* aBoard, SHAPE_POLY_SET& aOutline );
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter,
|
||||
void RENDER_3D_RAYTRACE_BASE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningReporter,
|
||||
bool aOnlyLoadCopperAndShapes )
|
||||
{
|
||||
m_reloadRequested = false;
|
||||
@ -962,7 +962,7 @@ void RENDER_3D_RAYTRACE::Reload( REPORTER* aStatusReporter, REPORTER* aWarningRe
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::insertHole( const PCB_VIA* aVia )
|
||||
void RENDER_3D_RAYTRACE_BASE::insertHole( const PCB_VIA* aVia )
|
||||
{
|
||||
PCB_LAYER_ID top_layer, bottom_layer;
|
||||
int radiusBUI = ( aVia->GetDrillValue() / 2 );
|
||||
@ -993,7 +993,7 @@ void RENDER_3D_RAYTRACE::insertHole( const PCB_VIA* aVia )
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::insertHole( const PAD* aPad )
|
||||
void RENDER_3D_RAYTRACE_BASE::insertHole( const PAD* aPad )
|
||||
{
|
||||
const OBJECT_2D* object2d_A = nullptr;
|
||||
|
||||
@ -1164,7 +1164,7 @@ void RENDER_3D_RAYTRACE::insertHole( const PAD* aPad )
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::addPadsAndVias()
|
||||
void RENDER_3D_RAYTRACE_BASE::addPadsAndVias()
|
||||
{
|
||||
if( !m_boardAdapter.GetBoard() )
|
||||
return;
|
||||
@ -1193,7 +1193,7 @@ void RENDER_3D_RAYTRACE::addPadsAndVias()
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMaterialInformation )
|
||||
void RENDER_3D_RAYTRACE_BASE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMaterialInformation )
|
||||
{
|
||||
if( !m_boardAdapter.GetBoard() )
|
||||
return;
|
||||
@ -1315,7 +1315,7 @@ void RENDER_3D_RAYTRACE::load3DModels( CONTAINER_3D& aDstContainer, bool aSkipMa
|
||||
}
|
||||
|
||||
|
||||
MODEL_MATERIALS* RENDER_3D_RAYTRACE::getModelMaterial( const S3DMODEL* a3DModel )
|
||||
MODEL_MATERIALS* RENDER_3D_RAYTRACE_BASE::getModelMaterial( const S3DMODEL* a3DModel )
|
||||
{
|
||||
MODEL_MATERIALS* materialVector;
|
||||
|
||||
@ -1418,7 +1418,7 @@ MODEL_MATERIALS* RENDER_3D_RAYTRACE::getModelMaterial( const S3DMODEL* a3DModel
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::addModels( CONTAINER_3D& aDstContainer, const S3DMODEL* a3DModel,
|
||||
void RENDER_3D_RAYTRACE_BASE::addModels( CONTAINER_3D& aDstContainer, const S3DMODEL* a3DModel,
|
||||
const glm::mat4& aModelMatrix, float aFPOpacity,
|
||||
bool aSkipMaterialInformation, BOARD_ITEM* aBoardItem )
|
||||
{
|
||||
|
@ -22,32 +22,28 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <gal/opengl/kiglew.h> // Must be included first
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "render_3d_raytrace.h"
|
||||
#include "render_3d_raytrace_base.h"
|
||||
#include "mortoncodes.h"
|
||||
#include "../color_rgba.h"
|
||||
#include "3d_fastmath.h"
|
||||
#include "3d_math.h"
|
||||
#include "../common_ogl/ogl_utils.h"
|
||||
#include <core/profile.h> // To use GetRunningMicroSecs or another profiling utility
|
||||
#include <wx/log.h>
|
||||
|
||||
|
||||
RENDER_3D_RAYTRACE::RENDER_3D_RAYTRACE( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdapter, CAMERA& aCamera ) :
|
||||
RENDER_3D_BASE( aCanvas, aAdapter, aCamera ),
|
||||
m_postShaderSsao( aCamera )
|
||||
RENDER_3D_RAYTRACE_BASE::RENDER_3D_RAYTRACE_BASE( BOARD_ADAPTER& aAdapter, CAMERA& aCamera ) :
|
||||
RENDER_3D_BASE( aAdapter, aCamera ),
|
||||
m_postShaderSsao( aCamera )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "RENDER_3D_RAYTRACE::RENDER_3D_RAYTRACE" ) );
|
||||
wxLogTrace( m_logTrace, wxT( "RENDER_3D_RAYTRACE_BASE::RENDER_3D_RAYTRACE_BASE" ) );
|
||||
|
||||
m_openglSupportsVertexBufferObjects = false;
|
||||
m_pboId = GL_NONE;
|
||||
m_pboDataSize = 0;
|
||||
//m_pboId = GL_NONE;
|
||||
//m_pboDataSize = 0;
|
||||
m_accelerator = nullptr;
|
||||
m_convertedDummyBlockCount = 0;
|
||||
m_converted2dRoundSegmentCount = 0;
|
||||
@ -62,6 +58,7 @@ RENDER_3D_RAYTRACE::RENDER_3D_RAYTRACE( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& a
|
||||
m_xoffset = 0;
|
||||
m_yoffset = 0;
|
||||
|
||||
m_is_canvas_initialized = false;
|
||||
m_isPreview = false;
|
||||
m_renderState = RT_RENDER_STATE_MAX; // Set to an initial invalid state
|
||||
m_renderStartTime = 0;
|
||||
@ -69,9 +66,9 @@ RENDER_3D_RAYTRACE::RENDER_3D_RAYTRACE( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& a
|
||||
}
|
||||
|
||||
|
||||
RENDER_3D_RAYTRACE::~RENDER_3D_RAYTRACE()
|
||||
RENDER_3D_RAYTRACE_BASE::~RENDER_3D_RAYTRACE_BASE()
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "RENDER_3D_RAYTRACE::~RENDER_3D_RAYTRACE" ) );
|
||||
wxLogTrace( m_logTrace, wxT( "RENDER_3D_RAYTRACE_BASE::~RENDER_3D_RAYTRACE_BASE" ) );
|
||||
|
||||
delete m_accelerator;
|
||||
m_accelerator = nullptr;
|
||||
@ -84,43 +81,16 @@ RENDER_3D_RAYTRACE::~RENDER_3D_RAYTRACE()
|
||||
|
||||
delete[] m_shaderBuffer;
|
||||
m_shaderBuffer = nullptr;
|
||||
|
||||
deletePbo();
|
||||
}
|
||||
|
||||
|
||||
int RENDER_3D_RAYTRACE::GetWaitForEditingTimeOut()
|
||||
int RENDER_3D_RAYTRACE_BASE::GetWaitForEditingTimeOut()
|
||||
{
|
||||
return 200; // ms
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::deletePbo()
|
||||
{
|
||||
// Delete PBO if it was created
|
||||
if( m_openglSupportsVertexBufferObjects )
|
||||
{
|
||||
if( glIsBufferARB( m_pboId ) )
|
||||
glDeleteBuffers( 1, &m_pboId );
|
||||
|
||||
m_pboId = GL_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::SetCurWindowSize( const wxSize& aSize )
|
||||
{
|
||||
if( m_windowSize != aSize )
|
||||
{
|
||||
m_windowSize = aSize;
|
||||
glViewport( 0, 0, m_windowSize.x, m_windowSize.y );
|
||||
|
||||
initializeNewWindowSize();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::restartRenderState()
|
||||
void RENDER_3D_RAYTRACE_BASE::restartRenderState()
|
||||
{
|
||||
m_renderStartTime = GetRunningMicroSecs();
|
||||
|
||||
@ -145,151 +115,13 @@ static inline void SetPixel( GLubyte* p, const COLOR_RGBA& v )
|
||||
}
|
||||
|
||||
|
||||
static inline SFVEC4F premultiplyAlpha( const SFVEC4F& aInput )
|
||||
SFVEC4F RENDER_3D_RAYTRACE_BASE::premultiplyAlpha( const SFVEC4F& aInput )
|
||||
{
|
||||
return SFVEC4F( aInput.r * aInput.a, aInput.g * aInput.a, aInput.b * aInput.a, aInput.a );
|
||||
}
|
||||
|
||||
|
||||
bool RENDER_3D_RAYTRACE::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
|
||||
REPORTER* aWarningReporter )
|
||||
{
|
||||
bool requestRedraw = false;
|
||||
|
||||
// Initialize openGL if need
|
||||
if( !m_is_opengl_initialized )
|
||||
{
|
||||
if( !initializeOpenGL() )
|
||||
return false;
|
||||
|
||||
//aIsMoving = true;
|
||||
requestRedraw = true;
|
||||
|
||||
// It will assign the first time the windows size, so it will now
|
||||
// revert to preview mode the first time the Redraw is called
|
||||
m_oldWindowsSize = m_windowSize;
|
||||
initializeBlockPositions();
|
||||
}
|
||||
|
||||
std::unique_ptr<BUSY_INDICATOR> busy = CreateBusyIndicator();
|
||||
|
||||
// Reload board if it was requested
|
||||
if( m_reloadRequested )
|
||||
{
|
||||
if( aStatusReporter )
|
||||
aStatusReporter->Report( _( "Loading..." ) );
|
||||
|
||||
//aIsMoving = true;
|
||||
requestRedraw = true;
|
||||
Reload( aStatusReporter, aWarningReporter, false );
|
||||
}
|
||||
|
||||
|
||||
// Recalculate constants if windows size was changed
|
||||
if( m_windowSize != m_oldWindowsSize )
|
||||
{
|
||||
m_oldWindowsSize = m_windowSize;
|
||||
aIsMoving = true;
|
||||
requestRedraw = true;
|
||||
|
||||
initializeBlockPositions();
|
||||
}
|
||||
|
||||
|
||||
// Clear buffers
|
||||
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
|
||||
glClearDepth( 1.0f );
|
||||
glClearStencil( 0x00 );
|
||||
glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
|
||||
|
||||
// 4-byte pixel alignment
|
||||
glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
|
||||
|
||||
glDisable( GL_STENCIL_TEST );
|
||||
glDisable( GL_LIGHTING );
|
||||
glDisable( GL_COLOR_MATERIAL );
|
||||
glDisable( GL_DEPTH_TEST );
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
glDisable( GL_BLEND );
|
||||
glDisable( GL_MULTISAMPLE );
|
||||
|
||||
const bool was_camera_changed = m_camera.ParametersChanged();
|
||||
|
||||
if( requestRedraw || aIsMoving || was_camera_changed )
|
||||
m_renderState = RT_RENDER_STATE_MAX; // Set to an invalid state,
|
||||
// so it will restart again latter
|
||||
|
||||
// This will only render if need, otherwise it will redraw the PBO on the screen again
|
||||
if( aIsMoving || was_camera_changed )
|
||||
{
|
||||
// Set head light (camera view light) with the opposite direction of the camera
|
||||
if( m_cameraLight )
|
||||
m_cameraLight->SetDirection( -m_camera.GetDir() );
|
||||
|
||||
OglDrawBackground( premultiplyAlpha( m_boardAdapter.m_BgColorTop ),
|
||||
premultiplyAlpha( m_boardAdapter.m_BgColorBot ) );
|
||||
|
||||
// Bind PBO
|
||||
glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
|
||||
|
||||
// Get the PBO pixel pointer to write the data
|
||||
GLubyte* ptrPBO = (GLubyte *)glMapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB,
|
||||
GL_WRITE_ONLY_ARB );
|
||||
|
||||
if( ptrPBO )
|
||||
{
|
||||
renderPreview( ptrPBO );
|
||||
|
||||
// release pointer to mapping buffer, this initialize the coping to PBO
|
||||
glUnmapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB );
|
||||
}
|
||||
|
||||
glWindowPos2i( m_xoffset, m_yoffset );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bind PBO
|
||||
glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
|
||||
|
||||
if( m_renderState != RT_RENDER_STATE_FINISH )
|
||||
{
|
||||
// Get the PBO pixel pointer to write the data
|
||||
GLubyte* ptrPBO = (GLubyte *)glMapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB,
|
||||
GL_WRITE_ONLY_ARB );
|
||||
|
||||
if( ptrPBO )
|
||||
{
|
||||
render( ptrPBO, aStatusReporter );
|
||||
|
||||
if( m_renderState != RT_RENDER_STATE_FINISH )
|
||||
requestRedraw = true;
|
||||
|
||||
// release pointer to mapping buffer, this initialize the coping to PBO
|
||||
glUnmapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_renderState == RT_RENDER_STATE_FINISH )
|
||||
{
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
}
|
||||
|
||||
glWindowPos2i( m_xoffset, m_yoffset );
|
||||
}
|
||||
|
||||
// This way it will blend the progress rendering with the last buffer. eg:
|
||||
// if it was called after a openGL.
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glEnable( GL_ALPHA_TEST );
|
||||
glDrawPixels( m_realBufferSize.x, m_realBufferSize.y, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
|
||||
glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
|
||||
|
||||
return requestRedraw;
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::render( GLubyte* ptrPBO, REPORTER* aStatusReporter )
|
||||
void RENDER_3D_RAYTRACE_BASE::render( GLubyte* ptrPBO, REPORTER* aStatusReporter )
|
||||
{
|
||||
if( ( m_renderState == RT_RENDER_STATE_FINISH ) || ( m_renderState >= RT_RENDER_STATE_MAX ) )
|
||||
{
|
||||
@ -342,14 +174,14 @@ void RENDER_3D_RAYTRACE::render( GLubyte* ptrPBO, REPORTER* aStatusReporter )
|
||||
if( aStatusReporter && ( m_renderState == RT_RENDER_STATE_FINISH ) )
|
||||
{
|
||||
// Calculation time in seconds
|
||||
const double elapsed_time = (double)( GetRunningMicroSecs() - m_renderStartTime ) / 1e6;
|
||||
const double elapsed_time = (double) ( GetRunningMicroSecs() - m_renderStartTime ) / 1e6;
|
||||
|
||||
aStatusReporter->Report( wxString::Format( _( "Rendering time %.3f s" ), elapsed_time ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::renderTracing( GLubyte* ptrPBO, REPORTER* aStatusReporter )
|
||||
void RENDER_3D_RAYTRACE_BASE::renderTracing( GLubyte* ptrPBO, REPORTER* aStatusReporter )
|
||||
{
|
||||
m_isPreview = false;
|
||||
|
||||
@ -364,6 +196,8 @@ void RENDER_3D_RAYTRACE::renderTracing( GLubyte* ptrPBO, REPORTER* aStatusReport
|
||||
std::max<size_t>( std::thread::hardware_concurrency(), 2 ),
|
||||
m_blockPositions.size() );
|
||||
|
||||
const int timeLimit = m_blockPositions.size() > 40000 ? 500 : 200;
|
||||
|
||||
for( size_t ii = 0; ii < parallelThreadCount; ++ii )
|
||||
{
|
||||
std::thread t = std::thread( [&]()
|
||||
@ -380,8 +214,10 @@ void RENDER_3D_RAYTRACE::renderTracing( GLubyte* ptrPBO, REPORTER* aStatusReport
|
||||
|
||||
// Check if it spend already some time render and request to exit
|
||||
// to display the progress
|
||||
if( std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now() - startTime ).count() > 150 )
|
||||
auto diff = std::chrono::duration_cast<std::chrono::milliseconds>(
|
||||
std::chrono::steady_clock::now() - startTime );
|
||||
|
||||
if( diff.count() > timeLimit )
|
||||
breakLoop = true;
|
||||
}
|
||||
}
|
||||
@ -459,7 +295,7 @@ SFVEC4F ConvertSRGBAToLinear( const SFVEC4F& aSRGBAcolor )
|
||||
#endif
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::renderFinalColor( GLubyte* ptrPBO, const SFVEC4F& rgbColor,
|
||||
void RENDER_3D_RAYTRACE_BASE::renderFinalColor( GLubyte* ptrPBO, const SFVEC4F& rgbColor,
|
||||
bool applyColorSpaceConversion )
|
||||
{
|
||||
SFVEC4F color = rgbColor;
|
||||
@ -494,7 +330,7 @@ static void HITINFO_PACKET_init( HITINFO_PACKET* aHitPacket )
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::renderRayPackets( const SFVEC4F* bgColorY, const RAY* aRayPkt,
|
||||
void RENDER_3D_RAYTRACE_BASE::renderRayPackets( const SFVEC4F* bgColorY, const RAY* aRayPkt,
|
||||
HITINFO_PACKET* aHitPacket, bool is_testShadow,
|
||||
SFVEC4F* aOutHitColor )
|
||||
{
|
||||
@ -516,7 +352,7 @@ void RENDER_3D_RAYTRACE::renderRayPackets( const SFVEC4F* bgColorY, const RAY* a
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::renderAntiAliasPackets( const SFVEC4F* aBgColorY,
|
||||
void RENDER_3D_RAYTRACE_BASE::renderAntiAliasPackets( const SFVEC4F* aBgColorY,
|
||||
const HITINFO_PACKET* aHitPck_X0Y0,
|
||||
const HITINFO_PACKET* aHitPck_AA_X1Y1,
|
||||
const RAY* aRayPck, SFVEC4F* aOutHitColor )
|
||||
@ -640,7 +476,7 @@ void RENDER_3D_RAYTRACE::renderAntiAliasPackets( const SFVEC4F* aBgColorY,
|
||||
#define DISP_FACTOR 0.075f
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock )
|
||||
void RENDER_3D_RAYTRACE_BASE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock )
|
||||
{
|
||||
// Initialize ray packets
|
||||
const SFVEC2UI& blockPos = m_blockPositions[iBlock];
|
||||
@ -851,7 +687,7 @@ void RENDER_3D_RAYTRACE::renderBlockTracing( GLubyte* ptrPBO, signed int iBlock
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::postProcessShading( GLubyte* /* ptrPBO */, REPORTER* aStatusReporter )
|
||||
void RENDER_3D_RAYTRACE_BASE::postProcessShading( GLubyte* /* ptrPBO */, REPORTER* aStatusReporter )
|
||||
{
|
||||
if( m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing )
|
||||
{
|
||||
@ -903,7 +739,7 @@ void RENDER_3D_RAYTRACE::postProcessShading( GLubyte* /* ptrPBO */, REPORTER* aS
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::postProcessBlurFinish( GLubyte* ptrPBO, REPORTER* /* aStatusReporter */ )
|
||||
void RENDER_3D_RAYTRACE_BASE::postProcessBlurFinish( GLubyte* ptrPBO, REPORTER* /* aStatusReporter */ )
|
||||
{
|
||||
if( m_boardAdapter.m_Cfg->m_Render.raytrace_post_processing )
|
||||
{
|
||||
@ -960,7 +796,7 @@ void RENDER_3D_RAYTRACE::postProcessBlurFinish( GLubyte* ptrPBO, REPORTER* /* aS
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
|
||||
void RENDER_3D_RAYTRACE_BASE::renderPreview( GLubyte* ptrPBO )
|
||||
{
|
||||
m_isPreview = true;
|
||||
|
||||
@ -1558,7 +1394,7 @@ void RENDER_3D_RAYTRACE::renderPreview( GLubyte* ptrPBO )
|
||||
|
||||
#define USE_EXPERIMENTAL_SOFT_SHADOWS 1
|
||||
|
||||
SFVEC4F RENDER_3D_RAYTRACE::shadeHit( const SFVEC4F& aBgColor, const RAY& aRay, HITINFO& aHitInfo,
|
||||
SFVEC4F RENDER_3D_RAYTRACE_BASE::shadeHit( const SFVEC4F& aBgColor, const RAY& aRay, HITINFO& aHitInfo,
|
||||
bool aIsInsideObject, unsigned int aRecursiveLevel,
|
||||
bool is_testShadow ) const
|
||||
{
|
||||
@ -1734,6 +1570,10 @@ SFVEC4F RENDER_3D_RAYTRACE::shadeHit( const SFVEC4F& aBgColor, const RAY& aRay,
|
||||
|
||||
sum_color += add;
|
||||
}
|
||||
else
|
||||
{
|
||||
sum_color += aBgColor;
|
||||
}
|
||||
}
|
||||
|
||||
outColor += (sum_color / SFVEC4F( (float)reflection_number_of_samples) );
|
||||
@ -1825,49 +1665,6 @@ SFVEC4F RENDER_3D_RAYTRACE::shadeHit( const SFVEC4F& aBgColor, const RAY& aRay,
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::initializeNewWindowSize()
|
||||
{
|
||||
initPbo();
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::initPbo()
|
||||
{
|
||||
if( GLEW_ARB_pixel_buffer_object )
|
||||
{
|
||||
m_openglSupportsVertexBufferObjects = true;
|
||||
|
||||
// Try to delete vbo if it was already initialized
|
||||
deletePbo();
|
||||
|
||||
// Learn about Pixel buffer objects at:
|
||||
// http://www.songho.ca/opengl/gl_pbo.html
|
||||
// http://web.eecs.umich.edu/~sugih/courses/eecs487/lectures/25-PBO+Mipmapping.pdf
|
||||
// "create 2 pixel buffer objects, you need to delete them when program exits.
|
||||
// glBufferDataARB with NULL pointer reserves only memory space."
|
||||
|
||||
// This sets the number of RGBA pixels
|
||||
m_pboDataSize = m_realBufferSize.x * m_realBufferSize.y * 4;
|
||||
|
||||
glGenBuffersARB( 1, &m_pboId );
|
||||
glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
|
||||
glBufferDataARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboDataSize, 0, GL_STREAM_DRAW_ARB );
|
||||
glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
|
||||
|
||||
wxLogTrace( m_logTrace,
|
||||
wxT( "RENDER_3D_RAYTRACE:: GLEW_ARB_pixel_buffer_object is supported" ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool RENDER_3D_RAYTRACE::initializeOpenGL()
|
||||
{
|
||||
m_is_opengl_initialized = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static float distance( const SFVEC2UI& a, const SFVEC2UI& b )
|
||||
{
|
||||
const float dx = (float) a.x - (float) b.x;
|
||||
@ -1876,7 +1673,7 @@ static float distance( const SFVEC2UI& a, const SFVEC2UI& b )
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE::initializeBlockPositions()
|
||||
void RENDER_3D_RAYTRACE_BASE::initializeBlockPositions()
|
||||
{
|
||||
m_realBufferSize = SFVEC2UI( 0 );
|
||||
|
||||
@ -1959,7 +1756,7 @@ void RENDER_3D_RAYTRACE::initializeBlockPositions()
|
||||
}
|
||||
|
||||
|
||||
BOARD_ITEM* RENDER_3D_RAYTRACE::IntersectBoardItem( const RAY& aRay )
|
||||
BOARD_ITEM* RENDER_3D_RAYTRACE_BASE::IntersectBoardItem( const RAY& aRay )
|
||||
{
|
||||
HITINFO hitInfo;
|
||||
hitInfo.m_tHit = std::numeric_limits<float>::infinity();
|
@ -22,10 +22,9 @@
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef RENDER_3D_RAYTRACE_H
|
||||
#define RENDER_3D_RAYTRACE_H
|
||||
#ifndef RENDER_3D_RAYTRACE_BASE_H
|
||||
#define RENDER_3D_RAYTRACE_BASE_H
|
||||
|
||||
#include "../../common_ogl/openGL_includes.h"
|
||||
#include "accelerators/container_3d.h"
|
||||
#include "accelerators/accelerator_3d.h"
|
||||
#include "../render_3d_base.h"
|
||||
@ -52,19 +51,16 @@ typedef enum
|
||||
} RT_RENDER_STATE;
|
||||
|
||||
|
||||
class RENDER_3D_RAYTRACE : public RENDER_3D_BASE
|
||||
class RENDER_3D_RAYTRACE_BASE : public RENDER_3D_BASE
|
||||
{
|
||||
public:
|
||||
// TODO: Take into account board thickness so that the camera won't move inside of the board
|
||||
// when facing it perpendicularly.
|
||||
static constexpr float MIN_DISTANCE_IU = 4 * PCB_IU_PER_MM;
|
||||
|
||||
explicit RENDER_3D_RAYTRACE( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdapter, CAMERA& aCamera );
|
||||
explicit RENDER_3D_RAYTRACE_BASE( BOARD_ADAPTER& aAdapter, CAMERA& aCamera );
|
||||
|
||||
~RENDER_3D_RAYTRACE();
|
||||
|
||||
void SetCurWindowSize( const wxSize& aSize ) override;
|
||||
bool Redraw( bool aIsMoving, REPORTER* aStatusReporter, REPORTER* aWarningReporter ) override;
|
||||
~RENDER_3D_RAYTRACE_BASE();
|
||||
|
||||
int GetWaitForEditingTimeOut() override;
|
||||
|
||||
@ -73,11 +69,9 @@ public:
|
||||
|
||||
BOARD_ITEM *IntersectBoardItem( const RAY& aRay );
|
||||
|
||||
private:
|
||||
bool initializeOpenGL();
|
||||
void initializeNewWindowSize();
|
||||
void initPbo();
|
||||
void deletePbo();
|
||||
protected:
|
||||
virtual void initPbo() = 0;
|
||||
virtual void deletePbo() = 0;
|
||||
void createItemsFromContainer( const BVH_CONTAINER_2D* aContainer2d, PCB_LAYER_ID aLayer_id,
|
||||
const MATERIAL* aMaterialLayer, const SFVEC3F& aLayerColor,
|
||||
float aLayerZOffset );
|
||||
@ -128,6 +122,8 @@ private:
|
||||
void render( GLubyte* ptrPBO, REPORTER* aStatusReporter );
|
||||
void renderPreview( GLubyte* ptrPBO );
|
||||
|
||||
static SFVEC4F premultiplyAlpha( const SFVEC4F& aInput );
|
||||
|
||||
struct
|
||||
{
|
||||
BLINN_PHONG_MATERIAL m_Paste;
|
||||
@ -148,6 +144,7 @@ private:
|
||||
BRUSHED_METAL_NORMAL m_brushedMetalMaterial;
|
||||
SILK_SCREEN_NORMAL m_silkScreenMaterial;
|
||||
|
||||
bool m_is_canvas_initialized;
|
||||
bool m_isPreview;
|
||||
|
||||
/// State used on quality render
|
||||
@ -165,10 +162,8 @@ private:
|
||||
|
||||
DIRECTIONAL_LIGHT* m_cameraLight;
|
||||
|
||||
bool m_openglSupportsVertexBufferObjects;
|
||||
|
||||
GLuint m_pboId;
|
||||
GLuint m_pboDataSize;
|
||||
/*GLuint m_pboId;
|
||||
GLuint m_pboDataSize;*/
|
||||
|
||||
CONTAINER_3D m_objectContainer;
|
||||
|
||||
@ -224,4 +219,4 @@ extern SFVEC4F ConvertSRGBAToLinear( const SFVEC4F& aSRGBAcolor );
|
||||
#define ConvertSRGBAToLinear( v ) ( v )
|
||||
#endif
|
||||
|
||||
#endif // RENDER_3D_RAYTRACE_H
|
||||
#endif // RENDER_3D_RAYTRACE_BASE_H
|
243
3d-viewer/3d_rendering/raytracing/render_3d_raytrace_gl.cpp
Normal file
243
3d-viewer/3d_rendering/raytracing/render_3d_raytrace_gl.cpp
Normal file
@ -0,0 +1,243 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2024 Alex Shvartzkop <dudesuchamazing@gmail.com>
|
||||
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include <gal/opengl/kiglew.h> // Must be included first
|
||||
|
||||
#include <algorithm>
|
||||
#include <atomic>
|
||||
#include <chrono>
|
||||
#include <thread>
|
||||
|
||||
#include "render_3d_raytrace_gl.h"
|
||||
#include "../common_ogl/ogl_utils.h"
|
||||
#include <core/profile.h> // To use GetRunningMicroSecs or another profiling utility
|
||||
#include <wx/log.h>
|
||||
|
||||
|
||||
RENDER_3D_RAYTRACE_GL::RENDER_3D_RAYTRACE_GL( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdapter, CAMERA& aCamera ) :
|
||||
RENDER_3D_RAYTRACE_BASE( aAdapter, aCamera )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "RENDER_3D_RAYTRACE_GL::RENDER_3D_RAYTRACE_GL" ) );
|
||||
|
||||
m_openglSupportsVertexBufferObjects = false;
|
||||
m_pboId = GL_NONE;
|
||||
m_pboDataSize = 0;
|
||||
}
|
||||
|
||||
|
||||
RENDER_3D_RAYTRACE_GL::~RENDER_3D_RAYTRACE_GL()
|
||||
{
|
||||
deletePbo();
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE_GL::deletePbo()
|
||||
{
|
||||
// Delete PBO if it was created
|
||||
if( m_openglSupportsVertexBufferObjects )
|
||||
{
|
||||
if( glIsBufferARB( m_pboId ) )
|
||||
glDeleteBuffers( 1, &m_pboId );
|
||||
|
||||
m_pboId = GL_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE_GL::SetCurWindowSize( const wxSize& aSize )
|
||||
{
|
||||
if( m_windowSize != aSize )
|
||||
{
|
||||
m_windowSize = aSize;
|
||||
glViewport( 0, 0, m_windowSize.x, m_windowSize.y );
|
||||
|
||||
initPbo();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool RENDER_3D_RAYTRACE_GL::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
|
||||
REPORTER* aWarningReporter )
|
||||
{
|
||||
bool requestRedraw = false;
|
||||
|
||||
// Initialize openGL if need
|
||||
if( !m_canvasInitialized )
|
||||
{
|
||||
m_canvasInitialized = true;
|
||||
|
||||
//aIsMoving = true;
|
||||
requestRedraw = true;
|
||||
|
||||
// It will assign the first time the windows size, so it will now
|
||||
// revert to preview mode the first time the Redraw is called
|
||||
m_oldWindowsSize = m_windowSize;
|
||||
initializeBlockPositions();
|
||||
}
|
||||
|
||||
std::unique_ptr<BUSY_INDICATOR> busy = CreateBusyIndicator();
|
||||
|
||||
// Reload board if it was requested
|
||||
if( m_reloadRequested )
|
||||
{
|
||||
if( aStatusReporter )
|
||||
aStatusReporter->Report( _( "Loading..." ) );
|
||||
|
||||
//aIsMoving = true;
|
||||
requestRedraw = true;
|
||||
Reload( aStatusReporter, aWarningReporter, false );
|
||||
}
|
||||
|
||||
|
||||
// Recalculate constants if windows size was changed
|
||||
if( m_windowSize != m_oldWindowsSize )
|
||||
{
|
||||
m_oldWindowsSize = m_windowSize;
|
||||
aIsMoving = true;
|
||||
requestRedraw = true;
|
||||
|
||||
initializeBlockPositions();
|
||||
}
|
||||
|
||||
// Clear buffers
|
||||
glClearColor( 0.0f, 0.0f, 0.0f, 0.0f );
|
||||
glClearDepth( 1.0f );
|
||||
glClearStencil( 0x00 );
|
||||
glClear( GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT );
|
||||
|
||||
// 4-byte pixel alignment
|
||||
glPixelStorei( GL_UNPACK_ALIGNMENT, 4 );
|
||||
|
||||
glDisable( GL_STENCIL_TEST );
|
||||
glDisable( GL_LIGHTING );
|
||||
glDisable( GL_COLOR_MATERIAL );
|
||||
glDisable( GL_DEPTH_TEST );
|
||||
glDisable( GL_TEXTURE_2D );
|
||||
glDisable( GL_BLEND );
|
||||
glDisable( GL_MULTISAMPLE );
|
||||
|
||||
const bool was_camera_changed = m_camera.ParametersChanged();
|
||||
|
||||
if( requestRedraw || aIsMoving || was_camera_changed )
|
||||
m_renderState = RT_RENDER_STATE_MAX; // Set to an invalid state,
|
||||
// so it will restart again latter
|
||||
|
||||
// This will only render if need, otherwise it will redraw the PBO on the screen again
|
||||
if( aIsMoving || was_camera_changed )
|
||||
{
|
||||
// Set head light (camera view light) with the opposite direction of the camera
|
||||
if( m_cameraLight )
|
||||
m_cameraLight->SetDirection( -m_camera.GetDir() );
|
||||
|
||||
OglDrawBackground( premultiplyAlpha( m_boardAdapter.m_BgColorTop ),
|
||||
premultiplyAlpha( m_boardAdapter.m_BgColorBot ) );
|
||||
|
||||
// Bind PBO
|
||||
glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
|
||||
|
||||
// Get the PBO pixel pointer to write the data
|
||||
GLubyte* ptrPBO = (GLubyte *)glMapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB,
|
||||
GL_WRITE_ONLY_ARB );
|
||||
|
||||
if( ptrPBO )
|
||||
{
|
||||
renderPreview( ptrPBO );
|
||||
|
||||
// release pointer to mapping buffer, this initialize the coping to PBO
|
||||
glUnmapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB );
|
||||
}
|
||||
|
||||
glWindowPos2i( m_xoffset, m_yoffset );
|
||||
}
|
||||
else
|
||||
{
|
||||
// Bind PBO
|
||||
glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
|
||||
|
||||
if( m_renderState != RT_RENDER_STATE_FINISH )
|
||||
{
|
||||
// Get the PBO pixel pointer to write the data
|
||||
GLubyte* ptrPBO = (GLubyte *)glMapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB,
|
||||
GL_WRITE_ONLY_ARB );
|
||||
|
||||
if( ptrPBO )
|
||||
{
|
||||
render( ptrPBO, aStatusReporter );
|
||||
|
||||
if( m_renderState != RT_RENDER_STATE_FINISH )
|
||||
requestRedraw = true;
|
||||
|
||||
// release pointer to mapping buffer, this initialize the coping to PBO
|
||||
glUnmapBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB );
|
||||
}
|
||||
}
|
||||
|
||||
if( m_renderState == RT_RENDER_STATE_FINISH )
|
||||
{
|
||||
glClear( GL_COLOR_BUFFER_BIT );
|
||||
}
|
||||
|
||||
glWindowPos2i( m_xoffset, m_yoffset );
|
||||
}
|
||||
|
||||
// This way it will blend the progress rendering with the last buffer. eg:
|
||||
// if it was called after a openGL.
|
||||
glEnable( GL_BLEND );
|
||||
glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
|
||||
glEnable( GL_ALPHA_TEST );
|
||||
glDrawPixels( m_realBufferSize.x, m_realBufferSize.y, GL_RGBA, GL_UNSIGNED_BYTE, 0 );
|
||||
glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
|
||||
|
||||
return requestRedraw;
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE_GL::initPbo()
|
||||
{
|
||||
if( GLEW_ARB_pixel_buffer_object )
|
||||
{
|
||||
m_openglSupportsVertexBufferObjects = true;
|
||||
|
||||
// Try to delete vbo if it was already initialized
|
||||
deletePbo();
|
||||
|
||||
// Learn about Pixel buffer objects at:
|
||||
// http://www.songho.ca/opengl/gl_pbo.html
|
||||
// http://web.eecs.umich.edu/~sugih/courses/eecs487/lectures/25-PBO+Mipmapping.pdf
|
||||
// "create 2 pixel buffer objects, you need to delete them when program exits.
|
||||
// glBufferDataARB with NULL pointer reserves only memory space."
|
||||
|
||||
// This sets the number of RGBA pixels
|
||||
m_pboDataSize = m_realBufferSize.x * m_realBufferSize.y * 4;
|
||||
|
||||
glGenBuffersARB( 1, &m_pboId );
|
||||
glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboId );
|
||||
glBufferDataARB( GL_PIXEL_UNPACK_BUFFER_ARB, m_pboDataSize, 0, GL_STREAM_DRAW_ARB );
|
||||
glBindBufferARB( GL_PIXEL_UNPACK_BUFFER_ARB, 0 );
|
||||
|
||||
wxLogTrace( m_logTrace,
|
||||
wxT( "RENDER_3D_RAYTRACE_GL:: GLEW_ARB_pixel_buffer_object is supported" ) );
|
||||
}
|
||||
}
|
54
3d-viewer/3d_rendering/raytracing/render_3d_raytrace_gl.h
Normal file
54
3d-viewer/3d_rendering/raytracing/render_3d_raytrace_gl.h
Normal file
@ -0,0 +1,54 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2024 Alex Shvartzkop <dudesuchamazing@gmail.com>
|
||||
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef RENDER_3D_RAYTRACE_GL_H
|
||||
#define RENDER_3D_RAYTRACE_GL_H
|
||||
|
||||
#include "../../common_ogl/openGL_includes.h"
|
||||
#include "render_3d_raytrace_base.h"
|
||||
|
||||
|
||||
class RENDER_3D_RAYTRACE_GL : public RENDER_3D_RAYTRACE_BASE
|
||||
{
|
||||
public:
|
||||
explicit RENDER_3D_RAYTRACE_GL( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aAdapter,
|
||||
CAMERA& aCamera );
|
||||
|
||||
~RENDER_3D_RAYTRACE_GL();
|
||||
|
||||
void SetCurWindowSize( const wxSize& aSize ) override;
|
||||
bool Redraw( bool aIsMoving, REPORTER* aStatusReporter, REPORTER* aWarningReporter ) override;
|
||||
|
||||
protected:
|
||||
void initPbo() override;
|
||||
void deletePbo() override;
|
||||
|
||||
bool m_openglSupportsVertexBufferObjects;
|
||||
GLuint m_pboId;
|
||||
GLuint m_pboDataSize;
|
||||
};
|
||||
|
||||
|
||||
#endif // RENDER_3D_RAYTRACE_GL_H
|
159
3d-viewer/3d_rendering/raytracing/render_3d_raytrace_ram.cpp
Normal file
159
3d-viewer/3d_rendering/raytracing/render_3d_raytrace_ram.cpp
Normal file
@ -0,0 +1,159 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2024 Alex Shvartzkop <dudesuchamazing@gmail.com>
|
||||
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#include "render_3d_raytrace_ram.h"
|
||||
#include <wx/log.h>
|
||||
|
||||
|
||||
RENDER_3D_RAYTRACE_RAM::RENDER_3D_RAYTRACE_RAM( BOARD_ADAPTER& aAdapter, CAMERA& aCamera ) :
|
||||
RENDER_3D_RAYTRACE_BASE( aAdapter, aCamera ),
|
||||
m_outputBuffer( nullptr ),
|
||||
m_pboDataSize( 0 )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
RENDER_3D_RAYTRACE_RAM::~RENDER_3D_RAYTRACE_RAM()
|
||||
{
|
||||
deletePbo();
|
||||
}
|
||||
|
||||
|
||||
GLubyte* RENDER_3D_RAYTRACE_RAM::GetBuffer()
|
||||
{
|
||||
return m_outputBuffer;
|
||||
}
|
||||
|
||||
|
||||
wxSize RENDER_3D_RAYTRACE_RAM::GetRealBufferSize()
|
||||
{
|
||||
return wxSize( m_realBufferSize.x, m_realBufferSize.y );
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE_RAM::deletePbo()
|
||||
{
|
||||
delete[] m_outputBuffer;
|
||||
m_outputBuffer = nullptr;
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE_RAM::SetCurWindowSize( const wxSize& aSize )
|
||||
{
|
||||
if( m_windowSize != aSize )
|
||||
{
|
||||
m_windowSize = aSize;
|
||||
|
||||
initPbo();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool RENDER_3D_RAYTRACE_RAM::Redraw( bool aIsMoving, REPORTER* aStatusReporter,
|
||||
REPORTER* aWarningReporter )
|
||||
{
|
||||
bool requestRedraw = false;
|
||||
|
||||
// Initialize openGL if need
|
||||
if( !m_canvasInitialized )
|
||||
{
|
||||
m_canvasInitialized = true;
|
||||
|
||||
//aIsMoving = true;
|
||||
requestRedraw = true;
|
||||
|
||||
// It will assign the first time the windows size, so it will now
|
||||
// revert to preview mode the first time the Redraw is called
|
||||
m_oldWindowsSize = m_windowSize;
|
||||
initializeBlockPositions();
|
||||
}
|
||||
|
||||
std::unique_ptr<BUSY_INDICATOR> busy = CreateBusyIndicator();
|
||||
|
||||
// Reload board if it was requested
|
||||
if( m_reloadRequested )
|
||||
{
|
||||
if( aStatusReporter )
|
||||
aStatusReporter->Report( _( "Loading..." ) );
|
||||
|
||||
//aIsMoving = true;
|
||||
requestRedraw = true;
|
||||
Reload( aStatusReporter, aWarningReporter, false );
|
||||
}
|
||||
|
||||
|
||||
// Recalculate constants if windows size was changed
|
||||
if( m_windowSize != m_oldWindowsSize )
|
||||
{
|
||||
m_oldWindowsSize = m_windowSize;
|
||||
aIsMoving = true;
|
||||
requestRedraw = true;
|
||||
|
||||
initializeBlockPositions();
|
||||
}
|
||||
|
||||
const bool was_camera_changed = m_camera.ParametersChanged();
|
||||
|
||||
if( requestRedraw || aIsMoving || was_camera_changed )
|
||||
m_renderState = RT_RENDER_STATE_MAX; // Set to an invalid state,
|
||||
// so it will restart again latter
|
||||
|
||||
// This will only render if need, otherwise it will redraw the PBO on the screen again
|
||||
if( aIsMoving || was_camera_changed )
|
||||
{
|
||||
// Set head light (camera view light) with the opposite direction of the camera
|
||||
if( m_cameraLight )
|
||||
m_cameraLight->SetDirection( -m_camera.GetDir() );
|
||||
|
||||
if( m_outputBuffer )
|
||||
{
|
||||
renderPreview( m_outputBuffer );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if( m_renderState != RT_RENDER_STATE_FINISH )
|
||||
{
|
||||
if( m_outputBuffer )
|
||||
{
|
||||
render( m_outputBuffer, aStatusReporter );
|
||||
|
||||
if( m_renderState != RT_RENDER_STATE_FINISH )
|
||||
requestRedraw = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return requestRedraw;
|
||||
}
|
||||
|
||||
|
||||
void RENDER_3D_RAYTRACE_RAM::initPbo()
|
||||
{
|
||||
deletePbo();
|
||||
|
||||
m_pboDataSize = m_realBufferSize.x * m_realBufferSize.y * 4;
|
||||
m_outputBuffer = new GLubyte[m_pboDataSize]();
|
||||
}
|
58
3d-viewer/3d_rendering/raytracing/render_3d_raytrace_ram.h
Normal file
58
3d-viewer/3d_rendering/raytracing/render_3d_raytrace_ram.h
Normal file
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2020 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2024 Alex Shvartzkop <dudesuchamazing@gmail.com>
|
||||
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, you may find one here:
|
||||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
||||
* or you may search the http://www.gnu.org website for the version 2 license,
|
||||
* or you may write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
|
||||
*/
|
||||
|
||||
#ifndef RENDER_3D_RAYTRACE_RAM_H
|
||||
#define RENDER_3D_RAYTRACE_RAM_H
|
||||
|
||||
#include "render_3d_raytrace_base.h"
|
||||
|
||||
|
||||
class RENDER_3D_RAYTRACE_RAM : public RENDER_3D_RAYTRACE_BASE
|
||||
{
|
||||
public:
|
||||
// TODO: Take into account board thickness so that the camera won't move inside of the board
|
||||
// when facing it perpendicularly.
|
||||
static constexpr float MIN_DISTANCE_IU = 4 * PCB_IU_PER_MM;
|
||||
|
||||
explicit RENDER_3D_RAYTRACE_RAM( BOARD_ADAPTER& aAdapter, CAMERA& aCamera );
|
||||
|
||||
~RENDER_3D_RAYTRACE_RAM();
|
||||
|
||||
GLubyte* GetBuffer();
|
||||
wxSize GetRealBufferSize();
|
||||
|
||||
void SetCurWindowSize( const wxSize& aSize ) override;
|
||||
bool Redraw( bool aIsMoving, REPORTER* aStatusReporter, REPORTER* aWarningReporter ) override;
|
||||
|
||||
private:
|
||||
void initPbo() override;
|
||||
void deletePbo() override;
|
||||
|
||||
GLubyte* m_outputBuffer;
|
||||
GLuint m_pboDataSize;
|
||||
};
|
||||
|
||||
|
||||
#endif // RENDER_3D_RAYTRACE_RAM_H
|
@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -44,13 +44,12 @@
|
||||
const wxChar* RENDER_3D_BASE::m_logTrace = wxT( "KI_TRACE_3D_RENDER" );
|
||||
|
||||
|
||||
RENDER_3D_BASE::RENDER_3D_BASE( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera ) :
|
||||
RENDER_3D_BASE::RENDER_3D_BASE( BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera ) :
|
||||
m_boardAdapter( aBoardAdapter ),
|
||||
m_camera( aCamera )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "RENDER_3D_BASE::RENDER_3D_BASE" ) );
|
||||
m_canvas = aCanvas;
|
||||
m_is_opengl_initialized = false;
|
||||
m_canvasInitialized = false;
|
||||
m_windowSize = wxSize( -1, -1 );
|
||||
m_reloadRequested = true;
|
||||
}
|
||||
|
@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -42,7 +42,7 @@
|
||||
class RENDER_3D_BASE
|
||||
{
|
||||
public:
|
||||
explicit RENDER_3D_BASE( EDA_3D_CANVAS* aCanvas, BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera );
|
||||
explicit RENDER_3D_BASE( BOARD_ADAPTER& aBoardAdapter, CAMERA& aCamera );
|
||||
|
||||
virtual ~RENDER_3D_BASE() = 0;
|
||||
|
||||
@ -98,16 +98,13 @@ protected:
|
||||
*/
|
||||
std::unique_ptr<BUSY_INDICATOR> CreateBusyIndicator() const;
|
||||
|
||||
///< the canvas to display the scene
|
||||
EDA_3D_CANVAS* m_canvas;
|
||||
|
||||
///< Settings reference in use for this render.
|
||||
BOARD_ADAPTER& m_boardAdapter;
|
||||
|
||||
CAMERA& m_camera;
|
||||
|
||||
///< Flag if the opengl specific for this render was already initialized.
|
||||
bool m_is_opengl_initialized;
|
||||
///< Flag if the canvas specific for this render was already initialized.
|
||||
bool m_canvasInitialized;
|
||||
|
||||
///< @todo This must be reviewed in order to flag change types.
|
||||
bool m_reloadRequested;
|
||||
|
@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -38,11 +38,24 @@
|
||||
// stdlib
|
||||
#include <algorithm>
|
||||
|
||||
TRACK_BALL::TRACK_BALL( float aInitialDistance ) :
|
||||
CAMERA( aInitialDistance )
|
||||
|
||||
TRACK_BALL::TRACK_BALL( float aInitialDistance ) : CAMERA( aInitialDistance )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "TRACK_BALL::TRACK_BALL" ) );
|
||||
initQuat();
|
||||
}
|
||||
|
||||
|
||||
TRACK_BALL::TRACK_BALL( SFVEC3F aInitPos, SFVEC3F aLookat, PROJECTION_TYPE aProjectionType ) :
|
||||
CAMERA( aInitPos, aLookat, aProjectionType )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "TRACK_BALL::TRACK_BALL" ) );
|
||||
initQuat();
|
||||
}
|
||||
|
||||
|
||||
void TRACK_BALL::initQuat()
|
||||
{
|
||||
memset( m_quat_t0, 0, sizeof( m_quat_t0 ) );
|
||||
memset( m_quat_t1, 0, sizeof( m_quat_t1 ) );
|
||||
|
||||
@ -50,6 +63,7 @@ TRACK_BALL::TRACK_BALL( float aInitialDistance ) :
|
||||
trackball( m_quat_t1, 0.0, 0.0, 0.0, 0.0 );
|
||||
}
|
||||
|
||||
|
||||
void TRACK_BALL::Drag( const wxPoint& aNewMousePosition )
|
||||
{
|
||||
m_parametersChanged = true;
|
||||
|
@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -37,6 +37,7 @@ class TRACK_BALL : public CAMERA
|
||||
{
|
||||
public:
|
||||
explicit TRACK_BALL( float aInitialDistance );
|
||||
explicit TRACK_BALL( SFVEC3F aInitPos, SFVEC3F aLookat, PROJECTION_TYPE aProjectionType );
|
||||
|
||||
virtual ~TRACK_BALL()
|
||||
{
|
||||
@ -57,6 +58,8 @@ public:
|
||||
void Interpolate( float t ) override;
|
||||
|
||||
private:
|
||||
void initQuat();
|
||||
|
||||
/**
|
||||
* interpolate quaternions of the trackball
|
||||
*/
|
||||
|
@ -3,7 +3,7 @@
|
||||
*
|
||||
* Copyright (C) 2020 Jon Evans <jon@craftyjon.com>
|
||||
* Copyright (C) 2023 CERN
|
||||
* Copyright (C) 2020-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2020-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
@ -23,7 +23,6 @@
|
||||
#define EDA_3D_VIEWER_SETTINGS_H_
|
||||
|
||||
#include <3d_enums.h>
|
||||
#include <common_ogl/ogl_attr_list.h>
|
||||
#include <plugins/3dapi/xv3d_types.h>
|
||||
#include <settings/app_settings.h>
|
||||
#include <settings/parameters.h>
|
||||
@ -34,6 +33,8 @@
|
||||
#define FOLLOW_PLOT_SETTINGS wxT( "follow_plot_settings" )
|
||||
#define LEGACY_PRESET_FLAG wxT( "legacy_preset_flag" )
|
||||
|
||||
enum class ANTIALIASING_MODE;
|
||||
|
||||
|
||||
struct LAYER_PRESET_3D
|
||||
{
|
||||
|
@ -45,7 +45,9 @@ set(3D-VIEWER_SRCS
|
||||
${DIR_RAY_ACC}/container_2d.cpp
|
||||
${DIR_RAY}/PerlinNoise.cpp
|
||||
${DIR_RAY}/create_scene.cpp
|
||||
${DIR_RAY}/render_3d_raytrace.cpp
|
||||
${DIR_RAY}/render_3d_raytrace_base.cpp
|
||||
${DIR_RAY}/render_3d_raytrace_gl.cpp
|
||||
${DIR_RAY}/render_3d_raytrace_ram.cpp
|
||||
${DIR_RAY}/frustum.cpp
|
||||
${DIR_RAY}/material.cpp
|
||||
${DIR_RAY}/mortoncodes.cpp
|
||||
|
@ -88,6 +88,7 @@ set( KICOMMON_SRCS
|
||||
jobs/job_export_sch_pythonbom.cpp
|
||||
jobs/job_fp_export_svg.cpp
|
||||
jobs/job_fp_upgrade.cpp
|
||||
jobs/job_pcb_render.cpp
|
||||
jobs/job_pcb_drc.cpp
|
||||
jobs/job_sch_erc.cpp
|
||||
jobs/job_sym_export_svg.cpp
|
||||
|
@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2015-2020 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -29,6 +29,7 @@
|
||||
#include <gal/3d/camera.h>
|
||||
#include <wx/log.h>
|
||||
#include <algorithm>
|
||||
#include <3d_enums.h>
|
||||
|
||||
// A helper function to normalize aAngle between -2PI and +2PI
|
||||
inline void normalise2PI( float& aAngle )
|
||||
@ -50,15 +51,22 @@ const float CAMERA::DEFAULT_MIN_ZOOM = 0.020f;
|
||||
const float CAMERA::DEFAULT_MAX_ZOOM = 2.0f;
|
||||
|
||||
|
||||
CAMERA::CAMERA( float aInitialDistance )
|
||||
CAMERA::CAMERA( float aInitialDistance ) :
|
||||
CAMERA( SFVEC3F( 0.0f, 0.0f, -aInitialDistance ), SFVEC3F( 0.0f ),
|
||||
PROJECTION_TYPE::PERSPECTIVE )
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
CAMERA::CAMERA( SFVEC3F aInitPos, SFVEC3F aLookat, PROJECTION_TYPE aProjectionType )
|
||||
{
|
||||
wxLogTrace( m_logTrace, wxT( "CAMERA::CAMERA" ) );
|
||||
|
||||
m_camera_pos_init = SFVEC3F( 0.0f, 0.0f, -aInitialDistance );
|
||||
m_board_lookat_pos_init = SFVEC3F( 0.0f );
|
||||
m_windowSize = SFVEC2I( 0, 0 );
|
||||
m_projectionType = PROJECTION_TYPE::PERSPECTIVE;
|
||||
m_interpolation_mode = CAMERA_INTERPOLATION::BEZIER;
|
||||
m_camera_pos_init = aInitPos;
|
||||
m_board_lookat_pos_init = aLookat;
|
||||
m_windowSize = SFVEC2I( 0, 0 );
|
||||
m_projectionType = aProjectionType;
|
||||
m_interpolation_mode = CAMERA_INTERPOLATION::BEZIER;
|
||||
|
||||
m_minZoom = DEFAULT_MIN_ZOOM;
|
||||
m_maxZoom = DEFAULT_MAX_ZOOM;
|
||||
@ -99,6 +107,57 @@ void CAMERA::Reset()
|
||||
}
|
||||
|
||||
|
||||
bool CAMERA::ViewCommand_T1( VIEW3D_TYPE aRequestedView )
|
||||
{
|
||||
switch( aRequestedView )
|
||||
{
|
||||
case VIEW3D_TYPE::VIEW3D_RIGHT:
|
||||
SetT0_and_T1_current_T();
|
||||
Reset_T1();
|
||||
RotateZ_T1( glm::radians( -90.0f ) );
|
||||
RotateX_T1( glm::radians( -90.0f ) );
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_LEFT:
|
||||
Reset_T1();
|
||||
RotateZ_T1( glm::radians( 90.0f ) );
|
||||
RotateX_T1( glm::radians( -90.0f ) );
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_FRONT:
|
||||
Reset_T1();
|
||||
RotateX_T1( glm::radians( -90.0f ) );
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_BACK:
|
||||
Reset_T1();
|
||||
RotateX_T1( glm::radians( -90.0f ) );
|
||||
|
||||
// The rotation angle should be 180.
|
||||
// We use 179.999 (180 - epsilon) to avoid a full 360 deg rotation when
|
||||
// using 180 deg if the previous rotated position was already 180 deg
|
||||
RotateZ_T1( glm::radians( 179.999f ) );
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_TOP:
|
||||
Reset_T1();
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_BOTTOM:
|
||||
Reset_T1();
|
||||
RotateY_T1( glm::radians( 179.999f ) ); // Rotation = 180 - epsilon
|
||||
return true;
|
||||
|
||||
case VIEW3D_TYPE::VIEW3D_FLIP:
|
||||
RotateY_T1( glm::radians( 179.999f ) );
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void CAMERA::Reset_T1()
|
||||
{
|
||||
m_camera_pos_t1 = m_camera_pos_init;
|
||||
|
28
common/jobs/job_pcb_render.cpp
Normal file
28
common/jobs/job_pcb_render.cpp
Normal file
@ -0,0 +1,28 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2023 Mark Roszko <mark.roszko@gmail.com>
|
||||
* Copyright (C) 2024 Alex Shvartzkop <dudesuchamazing@gmail.com>
|
||||
* Copyright (C) 2023-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <jobs/job_pcb_render.h>
|
||||
|
||||
|
||||
JOB_PCB_RENDER::JOB_PCB_RENDER( bool aIsCli ) :
|
||||
JOB( "render", aIsCli ), m_filename(), m_outputFile()
|
||||
{
|
||||
}
|
84
common/jobs/job_pcb_render.h
Normal file
84
common/jobs/job_pcb_render.h
Normal file
@ -0,0 +1,84 @@
|
||||
/*
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
|
||||
* Copyright (C) 2024 Alex Shvartzkop <dudesuchamazing@gmail.com>
|
||||
* Copyright (C) 1992-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the
|
||||
* Free Software Foundation, either version 3 of the License, or (at your
|
||||
* option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#ifndef JOB_PCB_RENDER_H
|
||||
#define JOB_PCB_RENDER_H
|
||||
|
||||
#include <kicommon.h>
|
||||
#include <wx/string.h>
|
||||
#include "job.h"
|
||||
#include <optional>
|
||||
#include <math/vector3.h>
|
||||
|
||||
class KICOMMON_API JOB_PCB_RENDER : public JOB
|
||||
{
|
||||
public:
|
||||
JOB_PCB_RENDER( bool aIsCli );
|
||||
|
||||
wxString m_filename;
|
||||
wxString m_outputFile;
|
||||
|
||||
enum class FORMAT
|
||||
{
|
||||
PNG,
|
||||
JPEG
|
||||
};
|
||||
|
||||
enum class QUALITY
|
||||
{
|
||||
BASIC,
|
||||
HIGH,
|
||||
USER
|
||||
};
|
||||
|
||||
enum class BG_STYLE
|
||||
{
|
||||
DEFAULT,
|
||||
TRANSPARENT,
|
||||
OPAQUE
|
||||
};
|
||||
|
||||
enum class SIDE
|
||||
{
|
||||
TOP,
|
||||
BOTTOM,
|
||||
LEFT,
|
||||
RIGHT,
|
||||
FRONT,
|
||||
BACK
|
||||
};
|
||||
|
||||
FORMAT m_format = FORMAT::PNG;
|
||||
QUALITY m_quality = QUALITY::BASIC;
|
||||
BG_STYLE m_bgStyle = BG_STYLE::DEFAULT;
|
||||
int m_width = 0;
|
||||
int m_height = 0;
|
||||
std::string m_colorPreset;
|
||||
SIDE m_side = SIDE::TOP;
|
||||
double m_zoom = 1.0;
|
||||
bool m_perspective = false;
|
||||
VECTOR3D m_rotation;
|
||||
VECTOR3D m_pan;
|
||||
VECTOR3D m_pivot;
|
||||
bool m_floor = false;
|
||||
};
|
||||
|
||||
#endif
|
@ -2,7 +2,7 @@
|
||||
* This program source code file is part of KiCad, a free EDA CAD application.
|
||||
*
|
||||
* Copyright (C) 2015-2016 Mario Luzeiro <mrluzeiro@ua.pt>
|
||||
* Copyright (C) 2015-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
* Copyright (C) 2015-2024 KiCad Developers, see AUTHORS.txt for contributors.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
@ -34,6 +34,7 @@
|
||||
#include <plugins/3dapi/xv3d_types.h>
|
||||
#include <wx/gdicmn.h> // for wxSize
|
||||
#include <vector>
|
||||
#include <3d_enums.h>
|
||||
|
||||
enum class PROJECTION_TYPE
|
||||
{
|
||||
@ -110,6 +111,7 @@ public:
|
||||
* @param aInitialDistance Initial Z-distance to the board
|
||||
*/
|
||||
explicit CAMERA( float aInitialDistance );
|
||||
explicit CAMERA( SFVEC3F aInitPos, SFVEC3F aLookat, PROJECTION_TYPE aProjectionType );
|
||||
|
||||
virtual ~CAMERA()
|
||||
{
|
||||
@ -232,6 +234,8 @@ public:
|
||||
zoomChanged();
|
||||
}
|
||||
|
||||
bool ViewCommand_T1( VIEW3D_TYPE aRequestedView );
|
||||
|
||||
void RotateX( float aAngleInRadians );
|
||||
void RotateY( float aAngleInRadians );
|
||||
void RotateZ( float aAngleInRadians );
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user