From 9446a9166d21f5d03d54a16d8d41e451e2e009c9 Mon Sep 17 00:00:00 2001 From: Mario Luzeiro Date: Sat, 25 Apr 2020 15:38:41 +0100 Subject: [PATCH] 3D-Viewer: implement opacity in raytracing fix opacity implementation on OpenGL --- .../c3d_render_ogl_legacy.cpp | 32 ++++++++++++- .../3d_render_ogl_legacy/c_ogl_3dmodel.cpp | 45 ++----------------- .../c3d_render_createscene.cpp | 16 ++++--- .../c3d_render_raytracing.cpp | 12 ++--- .../c3d_render_raytracing.h | 7 +-- .../3d_render_raytracing/cmaterial.cpp | 6 +-- .../shapes2D/cobject2d.cpp | 6 +-- .../3d_render_raytracing/shapes3D/cobject.cpp | 7 +-- .../3d_render_raytracing/shapes3D/cobject.h | 10 ++++- 9 files changed, 73 insertions(+), 68 deletions(-) diff --git a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.cpp b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.cpp index 002084e329..88ff01cb4d 100644 --- a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.cpp +++ b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c3d_render_ogl_legacy.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2015-2016 Mario Luzeiro + * Copyright (C) 2015-2020 Mario Luzeiro * Copyright (C) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or @@ -863,9 +863,39 @@ bool C3D_RENDER_OGL_LEGACY::Redraw( // ///////////////////////////////////////////////////////////////////////// // !TODO: this can be optimized. If there are no transparent models (or no opacity), // then there is no need to make this function call. + + glDepthMask( GL_FALSE ); + + glEnable( GL_BLEND ); + glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + + // Enables Texture Env so it can combine model transparency with + // each module opacity setting + glEnable( GL_TEXTURE_2D ); + glActiveTexture( GL_TEXTURE0 ); + + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); + glTexEnvf( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE ); + glTexEnvf( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE ); + + glTexEnvi( GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR ); + + glTexEnvi( GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR ); + + glTexEnvi( GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA ); + glTexEnvi( GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_CONSTANT ); + glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_CONSTANT ); + render_3D_models( false, true ); render_3D_models( true, true ); + glDisable( GL_BLEND ); + OGL_ResetTextureStateDefaults(); + + glDepthMask( GL_TRUE ); // Render Grid // ///////////////////////////////////////////////////////////////////////// diff --git a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c_ogl_3dmodel.cpp b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c_ogl_3dmodel.cpp index 68b12711ba..338fe5b661 100644 --- a/3d-viewer/3d_rendering/3d_render_ogl_legacy/c_ogl_3dmodel.cpp +++ b/3d-viewer/3d_rendering/3d_render_ogl_legacy/c_ogl_3dmodel.cpp @@ -2,8 +2,8 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2020 Oleg Endo - * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 Mario Luzeiro + * Copyright (C) 1992-2020 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 @@ -414,36 +414,9 @@ void C_OGL_3DMODEL::Draw( bool aTransparent, float aOpacity ) const glTexCoordPointer( 2, GL_FLOAT, sizeof( VERTEX ), reinterpret_cast( offsetof( VERTEX, m_tex_uv ) ) ); - if( aTransparent ) - { - glEnable( GL_BLEND ); - glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); + const SFVEC4F param = SFVEC4F( 1.0f, 1.0f, 1.0f, aOpacity ); - if( aOpacity < 1.0f ) - { - glEnable( GL_TEXTURE_2D ); - glActiveTexture( GL_TEXTURE0 ); - - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE ); - glTexEnvf( GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE ); - glTexEnvf( GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_MODULATE ); - - glTexEnvi( GL_TEXTURE_ENV, GL_SRC0_RGB, GL_PRIMARY_COLOR ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB, GL_SRC_COLOR ); - - glTexEnvi( GL_TEXTURE_ENV, GL_SRC1_RGB, GL_PREVIOUS ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB, GL_SRC_COLOR ); - - glTexEnvi( GL_TEXTURE_ENV, GL_SRC0_ALPHA, GL_PRIMARY_COLOR ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_ALPHA, GL_SRC_ALPHA ); - glTexEnvi( GL_TEXTURE_ENV, GL_SRC1_ALPHA, GL_CONSTANT ); - glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA, GL_CONSTANT ); - - const SFVEC4F param = SFVEC4F( 1.0f, 1.0f, 1.0f, aOpacity ); - - glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const float*)¶m.x ); - } - } + glTexEnvfv( GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, (const float*)¶m.x ); // BeginDrawMulti(); @@ -476,16 +449,6 @@ void C_OGL_3DMODEL::Draw( bool aTransparent, float aOpacity ) const } // EndDrawMulti(); - - if( aTransparent ) - { - glDisable( GL_BLEND ); - - if( aOpacity < 1.0f ) - { - OGL_ResetTextureStateDefaults(); - } - } } C_OGL_3DMODEL::~C_OGL_3DMODEL() diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp index ab73d6bdea..c53c1ac3b1 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_createscene.cpp @@ -1335,13 +1335,14 @@ void C3D_RENDER_RAYTRACING::load_3D_models() while( sM != eM ) { - if( sM->m_Show && !sM->m_Filename.empty() ) + if( ( (float)sM->m_Opacity > FLT_EPSILON ) && + ( sM->m_Show && !sM->m_Filename.empty() ) ) { // get it from cache const S3DMODEL *modelPtr = cacheMgr->GetModel( sM->m_Filename ); // only add it if the return is not NULL - if( modelPtr ) + if( modelPtr ) { glm::mat4 modelMatrix = moduleMatrix; @@ -1370,7 +1371,7 @@ void C3D_RENDER_RAYTRACING::load_3D_models() sM->m_Scale.y, sM->m_Scale.z ) ); - add_3D_models( modelPtr, modelMatrix ); + add_3D_models( modelPtr, modelMatrix, (float)sM->m_Opacity ); } } @@ -1382,7 +1383,8 @@ void C3D_RENDER_RAYTRACING::load_3D_models() void C3D_RENDER_RAYTRACING::add_3D_models( const S3DMODEL *a3DModel, - const glm::mat4 &aModelMatrix ) + const glm::mat4 &aModelMatrix, + float aModuleOpacity ) { // Validate a3DModel pointers @@ -1591,11 +1593,13 @@ void C3D_RENDER_RAYTRACING::add_3D_models( const S3DMODEL *a3DModel, CTRIANGLE *newTriangle = new CTRIANGLE( vt0, vt2, vt1, nt0, nt2, nt1 ); - - m_object_container.Add( newTriangle ); newTriangle->SetMaterial( (const CMATERIAL *)&blinn_material ); + const float moduleTransparency = 1.0f - ( ( 1.0f - blinn_material.GetTransparency() ) * aModuleOpacity ); + + newTriangle->SetModelTransparency( moduleTransparency ); + if( mesh.m_Color == NULL ) { const SFVEC3F diffuseColor = diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp index 2f6a5b6932..e726919354 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.cpp @@ -1,8 +1,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 Mario Luzeiro + * Copyright (C) 1992-2020 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 @@ -1934,8 +1934,10 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor, // Refractions // ///////////////////////////////////////////////////////////////////// - if((objMaterial->GetTransparency() > 0.0f) && - m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_REFRACTIONS ) ) + const float objTransparency = aHitInfo.pHitObject->GetModelTransparency(); + + if( ( objTransparency > 0.0f ) && + m_boardAdapter.GetFlag( FL_RENDER_RAYTRACING_REFRACTIONS ) ) { const float airIndex = 1.000293f; const float glassIndex = 1.49f; @@ -1951,8 +1953,6 @@ SFVEC3F C3D_RENDER_RAYTRACING::shadeHit( const SFVEC3F &aBgColor, refractionRatio, refractedVector ) ) { - const float objTransparency = objMaterial->GetTransparency(); - // This increase the start point by a "fixed" factor so it will work the // same for all distances const SFVEC3F startPoint = aRay.at( NextFloatUp( diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h index 571f596e0c..5675513fff 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h +++ b/3d-viewer/3d_rendering/3d_render_raytracing/c3d_render_raytracing.h @@ -1,8 +1,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 Mario Luzeiro + * Copyright (C) 1992-2020 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 @@ -197,7 +197,8 @@ private: void insert3DPadHole( const D_PAD* aPad ); void load_3D_models(); void add_3D_models( const S3DMODEL *a3DModel, - const glm::mat4 &aModelMatrix ); + const glm::mat4 &aModelMatrix, + float aModuleOpacity ); /// Stores materials of the 3D models MAP_MODEL_MATERIALS m_model_materials; diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.cpp index 540633d7b8..0223344f2d 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/cmaterial.cpp @@ -1,8 +1,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 Mario Luzeiro + * Copyright (C) 1992-2020 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 @@ -74,7 +74,7 @@ CMATERIAL::CMATERIAL( const SFVEC3F &aAmbient, m_emissiveColor = aEmissive; m_specularColor = aSpecular; m_shinness = aShinness; - m_transparency = aTransparency; + m_transparency = glm::clamp( aTransparency, 0.0f, 1.0f ); m_absorbance = 1.0f; m_reflection = aReflection; m_cast_shadows = true; diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/shapes2D/cobject2d.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/shapes2D/cobject2d.cpp index 65a8ccfe86..403aad3bf6 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/shapes2D/cobject2d.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/shapes2D/cobject2d.cpp @@ -1,8 +1,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 Mario Luzeiro + * Copyright (C) 1992-2020 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 @@ -46,7 +46,7 @@ COBJECT2D::COBJECT2D( OBJECT2D_TYPE aObjType, const BOARD_ITEM &aBoardItem ) * Lookup table for OBJECT2D_TYPE printed names */ // clang-format off -const std::map objectTypeNames +const std::map objectTypeNames { { OBJECT2D_TYPE::FILLED_CIRCLE, "OBJECT2D_TYPE::FILLED_CIRCLE" }, { OBJECT2D_TYPE::CSG, "OBJECT2D_TYPE::CSG" }, diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/cobject.cpp b/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/cobject.cpp index 7e3248268b..d854b16c58 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/cobject.cpp +++ b/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/cobject.cpp @@ -41,6 +41,7 @@ COBJECT::COBJECT( OBJECT3D_TYPE aObjType ) m_obj_type = aObjType; COBJECT3D_STATS::Instance().AddOne( aObjType ); m_material = &s_defaultMaterial; + m_modelTransparency = 0.0f; } @@ -48,14 +49,14 @@ COBJECT::COBJECT( OBJECT3D_TYPE aObjType ) * Lookup table for OBJECT2D_TYPE printed names */ // clang-format off -const std::map objectTypeNames -{ +const std::map objectTypeNames +{ { OBJECT3D_TYPE::CYLINDER, "OBJECT3D_TYPE::CYLINDER" }, { OBJECT3D_TYPE::DUMMYBLOCK, "OBJECT2D_TYPE::DUMMYBLOCK" }, { OBJECT3D_TYPE::LAYERITEM, "OBJECT2D_TYPE::LAYERITEM" }, { OBJECT3D_TYPE::XYPLANE, "OBJECT2D_TYPE::XYPLANE" }, { OBJECT3D_TYPE::ROUNDSEG, "OBJECT2D_TYPE::ROUNDSEG" }, - { OBJECT3D_TYPE::TRIANGLE, "OBJECT2D_TYPE::TRIANGLE" } + { OBJECT3D_TYPE::TRIANGLE, "OBJECT2D_TYPE::TRIANGLE" } }; // clang-format on diff --git a/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/cobject.h b/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/cobject.h index a22bcca7a5..0fedab60c2 100644 --- a/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/cobject.h +++ b/3d-viewer/3d_rendering/3d_render_raytracing/shapes3D/cobject.h @@ -1,8 +1,8 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2015-2016 Mario Luzeiro - * Copyright (C) 1992-2016 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2015-2020 Mario Luzeiro + * Copyright (C) 1992-2020 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 @@ -55,12 +55,18 @@ protected: OBJECT3D_TYPE m_obj_type; const CMATERIAL *m_material; + // m_modelTransparency combines the material and model opacity + // 0.0 full opaque, 1.0 full transparent. + float m_modelTransparency; + public: explicit COBJECT( OBJECT3D_TYPE aObjType ); void SetMaterial( const CMATERIAL *aMaterial ) { m_material = aMaterial; } const CMATERIAL *GetMaterial() const { return m_material; } + float GetModelTransparency() const { return m_modelTransparency; } + void SetModelTransparency( float aModelTransparency ) { m_modelTransparency = aModelTransparency; } virtual SFVEC3F GetDiffuseColor( const HITINFO &aHitInfo ) const = 0;