2012-05-18 02:45:23 -05:00
//##################################################################################################
//
// Custom Visualization Core library
2013-09-20 08:22:29 -05:00
// Copyright (C) 2011-2013 Ceetron AS
//
// This library may be used under the terms of either the GNU General Public License or
// the GNU Lesser General Public License as follows:
//
// GNU General Public License Usage
// This library 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 library 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 at <<http://www.gnu.org/licenses/gpl.html>>
// for more details.
//
// GNU Lesser General Public License Usage
// This library is free software; you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library 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 Lesser General Public License at <<http://www.gnu.org/licenses/lgpl-2.1.html>>
// for more details.
2012-05-18 02:45:23 -05:00
//
//##################################################################################################
2013-09-20 08:22:29 -05:00
2012-05-18 02:45:23 -05:00
# include "cafEffectGenerator.h"
2017-02-28 11:41:16 -06:00
# include "cafEffectCache.h"
2012-05-18 02:45:23 -05:00
# include "cafUtils.h"
# include "cvfMatrixState.h"
2017-02-28 11:41:16 -06:00
# include "cvfRenderState_FF.h"
2012-10-02 03:17:52 -05:00
# include "cvfRenderStateBlending.h"
# include "cvfRenderStateCullFace.h"
# include "cvfRenderStateDepth.h"
2017-02-28 11:41:16 -06:00
# include "cvfRenderStateLine.h"
# include "cvfRenderStatePolygonMode.h"
# include "cvfRenderStatePolygonOffset.h"
# include "cvfRenderStateTextureBindings.h"
# include "cvfSampler.h"
# include "cvfShaderProgram.h"
# include "cvfShaderProgramGenerator.h"
# include "cvfShaderSourceProvider.h"
# include "cvfTexture.h"
# include "cvfTexture2D_FF.h"
# include "cvfTextureImage.h"
# include "cvfUniform.h"
2012-05-18 02:45:23 -05:00
# include <QtOpenGL/QGLFormat>
namespace caf {
2017-02-27 15:20:06 -06:00
//#############################################################################################################################
//#############################################################################################################################
static const char checkDiscard_Transparent_Fragments_inl [ ] =
" \n "
" #define CVF_CHECK_DISCARD_FRAGMENT_IMPL \n "
" \n "
" //-------------------------------------------------------------------------------------------------- \n "
" /// Check if fragment should be discarded based on alpha fragment value \n "
" //-------------------------------------------------------------------------------------------------- \n "
" void checkDiscardFragment() \n "
" { \n "
" vec4 color = srcFragment(); \n "
" if (color.a < 1.0) discard; \n "
" } \n " ;
2012-05-18 02:45:23 -05:00
2013-09-20 06:56:24 -05:00
//=============================================================================================================================
//=============================================================================================================================
2012-10-02 03:17:52 -05:00
static const char light_AmbientDiffuse_inl [ ] =
" \n "
" varying vec3 v_ecPosition; \n "
" varying vec3 v_ecNormal; \n "
2016-08-16 03:58:07 -05:00
" uniform vec3 u_ecLightPosition; \n "
2012-10-02 03:17:52 -05:00
" \n "
" //-------------------------------------------------------------------------------------------------- \n "
2016-08-16 03:58:07 -05:00
" /// lightFragment() - Simple Positional Headlight without Phong/specular component \n "
2012-10-02 03:17:52 -05:00
" /// \n "
" //-------------------------------------------------------------------------------------------------- \n "
" vec4 lightFragment(vec4 srcFragColor, float not_in_use_shadowFactor) \n "
" { \n "
" const float ambientIntensity = 0.2; \n "
" \n "
" // Light vector (from point to light source) \n "
2016-08-16 03:58:07 -05:00
" vec3 L = normalize(u_ecLightPosition - v_ecPosition); \n "
2012-10-02 03:17:52 -05:00
" \n "
" // Viewing vector (from point to eye) \n "
" // Since we are in eye space, the eye pos is at (0, 0, 0) \n "
" vec3 V = normalize(-v_ecPosition); \n "
" \n "
" vec3 N = normalize(v_ecNormal); \n "
" vec3 R = normalize(reflect(-L, N)); \n "
" \n "
" vec3 ambient = srcFragColor.rgb*ambientIntensity; \n "
" vec3 diffuse = srcFragColor.rgb*(1.0 - ambientIntensity)*abs(dot(N, L)); \n "
" \n "
" return vec4(ambient + diffuse, srcFragColor.a); \n "
" } \n " ;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf : : String CommonShaderSources : : light_AmbientDiffuse ( )
{
return cvf : : String ( light_AmbientDiffuse_inl ) ;
}
2013-12-17 06:11:46 -06:00
//--------------------------------------------------------------------------------------------------
/// Static helper to configure polygon offset render state from enum
//--------------------------------------------------------------------------------------------------
2014-04-08 01:37:22 -05:00
cvf : : ref < cvf : : RenderStatePolygonOffset > EffectGenerator : : createAndConfigurePolygonOffsetRenderState ( PolygonOffset polygonOffset )
2013-12-17 06:11:46 -06:00
{
cvf : : ref < cvf : : RenderStatePolygonOffset > rs = new cvf : : RenderStatePolygonOffset ;
if ( polygonOffset = = PO_NONE )
{
return rs ;
}
rs - > enableFillMode ( true ) ;
2013-12-18 05:13:44 -06:00
2013-12-17 06:11:46 -06:00
switch ( polygonOffset )
{
2013-12-18 05:13:44 -06:00
case PO_1 : rs - > setFactor ( 1.0f ) ; rs - > setUnits ( 1.0f ) ; break ;
case PO_2 : rs - > setFactor ( 2.0f ) ; rs - > setUnits ( 2.0f ) ; break ;
case PO_NEG_LARGE : rs - > setFactor ( - 1.0f ) ; rs - > setUnits ( - 30.0f ) ; break ;
2013-12-17 06:11:46 -06:00
default :
CVF_FAIL_MSG ( " Unhandled polygon offset enum " ) ;
}
return rs ;
}
2012-05-18 02:45:23 -05:00
//==================================================================================================
//
// EffectGenerator Base class
//
//==================================================================================================
EffectGenerator : : RenderingModeType EffectGenerator : : sm_renderingMode = SHADER_BASED ;
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void EffectGenerator : : setRenderingMode ( RenderingModeType effectType )
{
sm_renderingMode = effectType ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
EffectGenerator : : RenderingModeType EffectGenerator : : renderingMode ( )
{
return sm_renderingMode ;
}
//--------------------------------------------------------------------------------------------------
2015-07-29 07:19:43 -05:00
///
2012-05-18 02:45:23 -05:00
//--------------------------------------------------------------------------------------------------
2015-08-13 07:35:30 -05:00
cvf : : ref < cvf : : Effect > EffectGenerator : : generateCachedEffect ( ) const
2012-05-18 02:45:23 -05:00
{
2012-08-31 12:12:47 -05:00
cvf : : ref < cvf : : Effect > eff = caf : : EffectCache : : instance ( ) - > findEffect ( this ) ;
2015-07-29 07:19:43 -05:00
if ( eff . notNull ( ) ) return eff . p ( ) ;
2012-08-31 12:12:47 -05:00
2015-08-13 07:35:30 -05:00
eff = generateUnCachedEffect ( ) ;
2015-07-29 07:19:43 -05:00
caf : : EffectCache : : instance ( ) - > addEffect ( this , eff . p ( ) ) ;
return eff ;
}
//--------------------------------------------------------------------------------------------------
/// Creates a new effect using the settings in the inherited generator.
/// Creates a new effect and calls the correct update-Effect method dep. on the effect type (software/shader)
//--------------------------------------------------------------------------------------------------
2015-08-13 07:35:30 -05:00
cvf : : ref < cvf : : Effect > EffectGenerator : : generateUnCachedEffect ( ) const
2015-07-29 07:19:43 -05:00
{
cvf : : ref < cvf : : Effect > eff = new cvf : : Effect ;
2012-08-31 12:12:47 -05:00
2012-05-18 02:45:23 -05:00
if ( sm_renderingMode = = SHADER_BASED )
{
updateForShaderBasedRendering ( eff . p ( ) ) ;
}
else
{
updateForFixedFunctionRendering ( eff . p ( ) ) ;
}
return eff ;
}
2015-07-29 07:19:43 -05:00
2012-05-18 02:45:23 -05:00
//--------------------------------------------------------------------------------------------------
/// Updates the effect to the state defined by the inherited effect generator.
/// This can be used to update an effect used several places in the scene.
/// Will first reset the effect, and then call the correct updateEffect method implemented in the inherited generator.
//--------------------------------------------------------------------------------------------------
void EffectGenerator : : updateEffect ( cvf : : Effect * effect ) const
{
CVF_ASSERT ( effect ! = NULL ) ;
// Clear effect
effect - > setRenderStateSet ( NULL ) ;
effect - > setUniformSet ( NULL ) ;
effect - > setShaderProgram ( NULL ) ;
if ( sm_renderingMode = = SHADER_BASED )
{
updateForShaderBasedRendering ( effect ) ;
}
else
{
updateForFixedFunctionRendering ( effect ) ;
}
}
2012-08-31 12:12:47 -05:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void EffectGenerator : : clearEffectCache ( )
{
EffectCache : : instance ( ) - > clear ( ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void EffectGenerator : : releaseUnreferencedEffects ( )
{
EffectCache : : instance ( ) - > releaseUnreferencedEffects ( ) ;
}
2012-05-18 02:45:23 -05:00
//==================================================================================================
//
// SurfaceEffectGenerator
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-12-17 06:11:46 -06:00
SurfaceEffectGenerator : : SurfaceEffectGenerator ( const cvf : : Color4f & color , PolygonOffset polygonOffset )
2012-05-18 02:45:23 -05:00
{
m_color = color ;
m_polygonOffset = polygonOffset ;
2013-12-18 01:57:10 -06:00
m_cullBackfaces = FC_NONE ;
2013-12-18 05:13:44 -06:00
m_enableDepthWrite = true ;
2015-10-23 02:34:47 -05:00
m_enableLighting = true ;
2012-05-18 02:45:23 -05:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-12-17 06:11:46 -06:00
SurfaceEffectGenerator : : SurfaceEffectGenerator ( const cvf : : Color3f & color , PolygonOffset polygonOffset )
2012-05-18 02:45:23 -05:00
{
m_color = cvf : : Color4f ( color , 1.0f ) ;
m_polygonOffset = polygonOffset ;
2013-12-18 01:57:10 -06:00
m_cullBackfaces = FC_NONE ;
2013-12-18 05:13:44 -06:00
m_enableDepthWrite = true ;
2015-10-23 02:34:47 -05:00
m_enableLighting = true ;
2012-05-18 02:45:23 -05:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void SurfaceEffectGenerator : : updateForShaderBasedRendering ( cvf : : Effect * effect ) const
{
cvf : : ShaderProgramGenerator gen ( " SurfaceEffectGenerator " , cvf : : ShaderSourceProvider : : instance ( ) ) ;
gen . addVertexCode ( cvf : : ShaderSourceRepository : : vs_Standard ) ;
gen . addFragmentCode ( cvf : : ShaderSourceRepository : : src_Color ) ;
2015-10-23 02:34:47 -05:00
if ( m_enableLighting )
{
gen . addFragmentCode ( CommonShaderSources : : light_AmbientDiffuse ( ) ) ;
gen . addFragmentCode ( cvf : : ShaderSourceRepository : : fs_Standard ) ;
}
else
{
gen . addFragmentCode ( cvf : : ShaderSourceRepository : : fs_Unlit ) ;
}
2012-05-18 02:45:23 -05:00
cvf : : ref < cvf : : ShaderProgram > shaderProg = gen . generate ( ) ;
2016-08-16 03:58:07 -05:00
if ( m_enableLighting ) shaderProg - > setDefaultUniform ( new cvf : : UniformFloat ( " u_ecLightPosition " , cvf : : Vec3f ( 0.5 , 5.0 , 7.0 ) ) ) ;
2012-05-18 02:45:23 -05:00
cvf : : ref < cvf : : Effect > eff = effect ;
eff - > setShaderProgram ( shaderProg . p ( ) ) ;
eff - > setUniform ( new cvf : : UniformFloat ( " u_color " , m_color ) ) ;
2016-08-16 03:58:07 -05:00
2012-05-18 02:45:23 -05:00
this - > updateCommonEffect ( effect ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void SurfaceEffectGenerator : : updateForFixedFunctionRendering ( cvf : : Effect * effect ) const
{
cvf : : ref < cvf : : Effect > eff = effect ;
2012-10-02 03:17:52 -05:00
cvf : : ref < cvf : : RenderStateMaterial_FF > mat = new cvf : : RenderStateMaterial_FF ( m_color . toColor3f ( ) ) ;
2012-05-18 02:45:23 -05:00
mat - > setAlpha ( m_color . a ( ) ) ;
eff - > setRenderState ( mat . p ( ) ) ;
2012-10-02 03:17:52 -05:00
cvf : : ref < cvf : : RenderStateLighting_FF > lighting = new cvf : : RenderStateLighting_FF ;
2012-05-18 02:45:23 -05:00
lighting - > enableTwoSided ( true ) ;
2015-10-23 02:34:47 -05:00
lighting - > enable ( m_enableLighting ) ;
2012-05-18 02:45:23 -05:00
eff - > setRenderState ( lighting . p ( ) ) ;
this - > updateCommonEffect ( effect ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void SurfaceEffectGenerator : : updateCommonEffect ( cvf : : Effect * effect ) const
{
2013-12-17 06:11:46 -06:00
if ( m_polygonOffset ! = PO_NONE )
2012-05-18 02:45:23 -05:00
{
2014-04-08 01:37:22 -05:00
cvf : : ref < cvf : : RenderStatePolygonOffset > polyOffset = EffectGenerator : : createAndConfigurePolygonOffsetRenderState ( m_polygonOffset ) ;
2012-05-18 02:45:23 -05:00
effect - > setRenderState ( polyOffset . p ( ) ) ;
}
// Simple transparency
if ( m_color . a ( ) < 1.0f )
{
2012-10-02 03:17:52 -05:00
cvf : : ref < cvf : : RenderStateBlending > blender = new cvf : : RenderStateBlending ;
2012-05-18 02:45:23 -05:00
blender - > configureTransparencyBlending ( ) ;
effect - > setRenderState ( blender . p ( ) ) ;
}
2013-12-18 06:21:03 -06:00
// Face culling
2013-12-18 01:57:10 -06:00
if ( m_cullBackfaces ! = FC_NONE )
2012-05-18 02:45:23 -05:00
{
2012-10-02 03:17:52 -05:00
cvf : : ref < cvf : : RenderStateCullFace > faceCulling = new cvf : : RenderStateCullFace ;
2013-12-18 01:57:10 -06:00
if ( m_cullBackfaces = = FC_BACK )
{
faceCulling - > setMode ( cvf : : RenderStateCullFace : : BACK ) ;
}
else if ( m_cullBackfaces = = FC_FRONT )
{
faceCulling - > setMode ( cvf : : RenderStateCullFace : : FRONT ) ;
}
else if ( m_cullBackfaces = = FC_FRONT_AND_BACK )
{
faceCulling - > setMode ( cvf : : RenderStateCullFace : : FRONT_AND_BACK ) ;
}
2012-05-18 02:45:23 -05:00
effect - > setRenderState ( faceCulling . p ( ) ) ;
}
2013-12-18 05:13:44 -06:00
if ( ! m_enableDepthWrite )
{
cvf : : ref < cvf : : RenderStateDepth > depth = new cvf : : RenderStateDepth ;
depth - > enableDepthWrite ( false ) ;
effect - > setRenderState ( depth . p ( ) ) ;
}
2012-05-18 02:45:23 -05:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool SurfaceEffectGenerator : : isEqual ( const EffectGenerator * other ) const
{
const SurfaceEffectGenerator * otherSurfaceEffect = dynamic_cast < const SurfaceEffectGenerator * > ( other ) ;
if ( otherSurfaceEffect )
{
if ( m_color = = otherSurfaceEffect - > m_color
& & m_polygonOffset = = otherSurfaceEffect - > m_polygonOffset
2013-12-18 05:13:44 -06:00
& & m_enableDepthWrite = = otherSurfaceEffect - > m_enableDepthWrite
2015-10-23 02:34:47 -05:00
& & m_enableLighting = = otherSurfaceEffect - > m_enableLighting
2012-05-18 02:45:23 -05:00
& & m_cullBackfaces = = otherSurfaceEffect - > m_cullBackfaces )
{
return true ;
}
}
return false ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
EffectGenerator * SurfaceEffectGenerator : : copy ( ) const
{
SurfaceEffectGenerator * effGen = new SurfaceEffectGenerator ( m_color , m_polygonOffset ) ;
effGen - > m_cullBackfaces = m_cullBackfaces ;
2013-12-18 05:13:44 -06:00
effGen - > m_enableDepthWrite = m_enableDepthWrite ;
2015-10-23 02:34:47 -05:00
effGen - > m_enableLighting = m_enableLighting ;
2012-05-18 02:45:23 -05:00
return effGen ;
}
//==================================================================================================
//
// ScalarMapperEffectGenerator
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
2013-12-17 06:11:46 -06:00
ScalarMapperEffectGenerator : : ScalarMapperEffectGenerator ( const cvf : : ScalarMapper * scalarMapper , PolygonOffset polygonOffset )
2012-05-18 02:45:23 -05:00
: m_undefinedColor ( cvf : : Color3 : : GRAY )
{
m_scalarMapper = scalarMapper ;
m_polygonOffset = polygonOffset ;
m_opacityLevel = 1.0f ;
2013-12-18 06:53:32 -06:00
m_faceCulling = FC_NONE ;
2013-12-19 01:59:28 -06:00
m_enableDepthWrite = true ;
2015-06-17 08:00:20 -05:00
m_disableLighting = false ;
2017-02-27 15:20:06 -06:00
m_discardTransparentFragments = false ;
2012-05-18 02:45:23 -05:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ScalarMapperEffectGenerator : : updateForShaderBasedRendering ( cvf : : Effect * effect ) const
{
cvf : : ref < cvf : : Effect > eff = effect ;
cvf : : ShaderProgramGenerator gen ( " ScalarMapperEffectGenerator " , cvf : : ShaderSourceProvider : : instance ( ) ) ;
gen . addVertexCode ( cvf : : ShaderSourceRepository : : vs_Standard ) ;
gen . addFragmentCode ( cvf : : ShaderSourceRepository : : src_Texture ) ;
2017-02-27 15:20:06 -06:00
if ( m_discardTransparentFragments )
{
gen . addFragmentCode ( checkDiscard_Transparent_Fragments_inl ) ;
}
2015-06-17 08:00:20 -05:00
if ( m_disableLighting )
{
gen . addFragmentCode ( cvf : : ShaderSourceRepository : : fs_Unlit ) ;
}
else
{
gen . addFragmentCode ( CommonShaderSources : : light_AmbientDiffuse ( ) ) ;
gen . addFragmentCode ( cvf : : ShaderSourceRepository : : fs_Standard ) ;
}
2012-05-18 02:45:23 -05:00
2017-02-27 15:20:06 -06:00
2012-05-18 02:45:23 -05:00
cvf : : ref < cvf : : ShaderProgram > prog = gen . generate ( ) ;
eff - > setShaderProgram ( prog . p ( ) ) ;
2016-08-16 03:58:07 -05:00
if ( ! m_disableLighting ) prog - > setDefaultUniform ( new cvf : : UniformFloat ( " u_ecLightPosition " , cvf : : Vec3f ( 0.5 , 5.0 , 7.0 ) ) ) ;
2012-05-18 02:45:23 -05:00
// Result mapping texture
2012-08-31 12:12:47 -05:00
m_textureImage = new cvf : : TextureImage ( ) ;
m_scalarMapper - > updateTexture ( m_textureImage . p ( ) ) ;
2012-05-18 02:45:23 -05:00
2012-08-31 12:12:47 -05:00
cvf : : ref < cvf : : TextureImage > modTexImg = ScalarMapperEffectGenerator : : addAlphaAndUndefStripes ( m_textureImage . p ( ) , m_undefinedColor , m_opacityLevel ) ;
2012-05-18 02:45:23 -05:00
cvf : : ref < cvf : : Texture > texture = new cvf : : Texture ( modTexImg . p ( ) ) ;
cvf : : ref < cvf : : Sampler > sampler = new cvf : : Sampler ;
sampler - > setWrapMode ( cvf : : Sampler : : CLAMP_TO_EDGE ) ;
sampler - > setMinFilter ( cvf : : Sampler : : NEAREST ) ;
sampler - > setMagFilter ( cvf : : Sampler : : NEAREST ) ;
2012-10-02 03:17:52 -05:00
cvf : : ref < cvf : : RenderStateTextureBindings > texBind = new cvf : : RenderStateTextureBindings ;
2012-05-18 02:45:23 -05:00
texBind - > addBinding ( texture . p ( ) , sampler . p ( ) , " u_texture2D " ) ;
eff - > setRenderState ( texBind . p ( ) ) ;
// Hardware independent:
updateCommonEffect ( eff . p ( ) ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ScalarMapperEffectGenerator : : updateForFixedFunctionRendering ( cvf : : Effect * effect ) const
{
cvf : : ref < cvf : : Effect > eff = effect ;
2012-10-02 03:17:52 -05:00
cvf : : ref < cvf : : RenderStateMaterial_FF > mat = new cvf : : RenderStateMaterial_FF ( cvf : : Color3 : : WHITE ) ;
2012-05-18 02:45:23 -05:00
eff - > setRenderState ( mat . p ( ) ) ;
2012-10-02 03:17:52 -05:00
cvf : : ref < cvf : : RenderStateLighting_FF > lighting = new cvf : : RenderStateLighting_FF ;
2012-05-18 02:45:23 -05:00
lighting - > enableTwoSided ( true ) ;
2015-06-17 08:00:20 -05:00
lighting - > enable ( ! m_disableLighting ) ;
2012-05-18 02:45:23 -05:00
eff - > setRenderState ( lighting . p ( ) ) ;
// Result mapping texture
2012-08-31 12:12:47 -05:00
m_textureImage = new cvf : : TextureImage ;
m_scalarMapper - > updateTexture ( m_textureImage . p ( ) ) ;
2012-05-18 02:45:23 -05:00
2012-08-31 12:12:47 -05:00
cvf : : ref < cvf : : TextureImage > modTexImg = ScalarMapperEffectGenerator : : addAlphaAndUndefStripes ( m_textureImage . p ( ) , m_undefinedColor , m_opacityLevel ) ;
2012-05-18 02:45:23 -05:00
cvf : : ref < cvf : : Texture2D_FF > texture = new cvf : : Texture2D_FF ( modTexImg . p ( ) ) ;
texture - > setWrapMode ( cvf : : Texture2D_FF : : CLAMP ) ;
texture - > setMinFilter ( cvf : : Texture2D_FF : : NEAREST ) ;
texture - > setMagFilter ( cvf : : Texture2D_FF : : NEAREST ) ;
2012-10-02 03:17:52 -05:00
cvf : : ref < cvf : : RenderStateTextureMapping_FF > texMapping = new cvf : : RenderStateTextureMapping_FF ( texture . p ( ) ) ;
2012-05-18 02:45:23 -05:00
eff - > setRenderState ( texMapping . p ( ) ) ;
// Hardware independent:
updateCommonEffect ( eff . p ( ) ) ;
}
//--------------------------------------------------------------------------------------------------
/// It also modifies the texture, and adds two more pixel lines
/// one with a transparent version of the legend color, and one with color for undefined values
//--------------------------------------------------------------------------------------------------
void ScalarMapperEffectGenerator : : updateCommonEffect ( cvf : : Effect * effect ) const
{
CVF_ASSERT ( effect ) ;
2013-12-17 06:11:46 -06:00
if ( m_polygonOffset ! = PO_NONE )
2012-05-18 02:45:23 -05:00
{
2014-04-08 01:37:22 -05:00
cvf : : ref < cvf : : RenderStatePolygonOffset > polyOffset = EffectGenerator : : createAndConfigurePolygonOffsetRenderState ( m_polygonOffset ) ;
2012-05-18 02:45:23 -05:00
effect - > setRenderState ( polyOffset . p ( ) ) ;
}
// Simple transparency
if ( m_opacityLevel < 1.0f )
{
2012-10-02 03:17:52 -05:00
cvf : : ref < cvf : : RenderStateBlending > blender = new cvf : : RenderStateBlending ;
2012-05-18 02:45:23 -05:00
blender - > configureTransparencyBlending ( ) ;
effect - > setRenderState ( blender . p ( ) ) ;
}
// Backface culling
2013-12-18 06:53:32 -06:00
if ( m_faceCulling ! = FC_NONE )
2012-05-18 02:45:23 -05:00
{
2012-10-02 03:17:52 -05:00
cvf : : ref < cvf : : RenderStateCullFace > faceCulling = new cvf : : RenderStateCullFace ;
2013-12-18 06:53:32 -06:00
if ( m_faceCulling = = FC_BACK )
2013-12-18 01:57:10 -06:00
{
faceCulling - > setMode ( cvf : : RenderStateCullFace : : BACK ) ;
}
2013-12-18 06:53:32 -06:00
else if ( m_faceCulling = = FC_FRONT )
2013-12-18 01:57:10 -06:00
{
faceCulling - > setMode ( cvf : : RenderStateCullFace : : FRONT ) ;
}
2013-12-18 06:53:32 -06:00
else if ( m_faceCulling = = FC_FRONT_AND_BACK )
2013-12-18 01:57:10 -06:00
{
faceCulling - > setMode ( cvf : : RenderStateCullFace : : FRONT_AND_BACK ) ;
}
2012-05-18 02:45:23 -05:00
effect - > setRenderState ( faceCulling . p ( ) ) ;
}
2013-12-19 01:59:28 -06:00
if ( ! m_enableDepthWrite )
{
cvf : : ref < cvf : : RenderStateDepth > depth = new cvf : : RenderStateDepth ;
depth - > enableDepthWrite ( false ) ;
effect - > setRenderState ( depth . p ( ) ) ;
}
2012-05-18 02:45:23 -05:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool ScalarMapperEffectGenerator : : isEqual ( const EffectGenerator * other ) const
{
const ScalarMapperEffectGenerator * otherTextureResultEffect = dynamic_cast < const ScalarMapperEffectGenerator * > ( other ) ;
if ( otherTextureResultEffect )
{
if ( m_scalarMapper . p ( ) = = otherTextureResultEffect - > m_scalarMapper
& & m_polygonOffset = = otherTextureResultEffect - > m_polygonOffset
& & m_opacityLevel = = otherTextureResultEffect - > m_opacityLevel
& & m_undefinedColor = = otherTextureResultEffect - > m_undefinedColor
2013-12-19 01:59:28 -06:00
& & m_faceCulling = = otherTextureResultEffect - > m_faceCulling
2015-06-17 08:00:20 -05:00
& & m_enableDepthWrite = = otherTextureResultEffect - > m_enableDepthWrite
2017-02-27 15:20:06 -06:00
& & m_disableLighting = = otherTextureResultEffect - > m_disableLighting
& & m_discardTransparentFragments = = otherTextureResultEffect - > m_discardTransparentFragments )
2012-05-18 02:45:23 -05:00
{
2012-08-31 12:12:47 -05:00
cvf : : ref < cvf : : TextureImage > texImg2 = new cvf : : TextureImage ;
otherTextureResultEffect - > m_scalarMapper - > updateTexture ( texImg2 . p ( ) ) ;
return ScalarMapperEffectGenerator : : isImagesEqual ( m_textureImage . p ( ) , texImg2 . p ( ) ) ;
2012-05-18 02:45:23 -05:00
}
}
return false ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
EffectGenerator * ScalarMapperEffectGenerator : : copy ( ) const
{
ScalarMapperEffectGenerator * scEffGen = new ScalarMapperEffectGenerator ( m_scalarMapper . p ( ) , m_polygonOffset ) ;
2012-08-31 12:12:47 -05:00
scEffGen - > m_textureImage = m_textureImage ;
2012-05-18 02:45:23 -05:00
scEffGen - > m_opacityLevel = m_opacityLevel ;
scEffGen - > m_undefinedColor = m_undefinedColor ;
2013-12-18 06:53:32 -06:00
scEffGen - > m_faceCulling = m_faceCulling ;
2013-12-19 01:59:28 -06:00
scEffGen - > m_enableDepthWrite = m_enableDepthWrite ;
2015-06-17 08:00:20 -05:00
scEffGen - > m_disableLighting = m_disableLighting ;
2017-02-27 15:20:06 -06:00
scEffGen - > m_discardTransparentFragments = m_discardTransparentFragments ;
2012-05-18 02:45:23 -05:00
return scEffGen ;
}
//--------------------------------------------------------------------------------------------------
/// Modifies the supplied one line texture by adding two more pixel lines
/// one with a transparent version of the legend color, and one with color for undefined values
//--------------------------------------------------------------------------------------------------
cvf : : ref < cvf : : TextureImage >
ScalarMapperEffectGenerator : : addAlphaAndUndefStripes ( const cvf : : TextureImage * texImg , const cvf : : Color3f & undefScalarColor , float opacityLevel )
{
CVF_ASSERT ( texImg ! = NULL ) ;
CVF_ASSERT ( texImg - > height ( ) = = 1 ) ;
cvf : : ref < cvf : : TextureImage > modTexImg = new cvf : : TextureImage ;
2013-09-06 02:44:57 -05:00
modTexImg - > allocate ( texImg - > width ( ) , texImg - > height ( ) + 3 ) ; // Make the texture a power of two to avoid behind the scenes scaling and the following artefacts
2012-05-18 02:45:23 -05:00
modTexImg - > fill ( cvf : : Color4ub ( cvf : : Color3ub ( undefScalarColor ) , 255 ) ) ; // Undefined color
2013-01-22 04:34:47 -06:00
for ( cvf : : uint i = 0 ; i < texImg - > width ( ) ; + + i )
2012-05-18 02:45:23 -05:00
{
cvf : : Color4ub legendColor = texImg - > pixel ( i , 0 ) ;
modTexImg - > setPixel ( i , 0 , legendColor ) ;
legendColor . a ( ) = static_cast < cvf : : ubyte > ( opacityLevel * 255 ) ;
modTexImg - > setPixel ( i , 1 , legendColor ) ;
2013-09-06 02:44:57 -05:00
modTexImg - > setPixel ( i , 2 , legendColor ) ;
2012-05-18 02:45:23 -05:00
}
return modTexImg ;
}
2012-08-31 12:12:47 -05:00
//--------------------------------------------------------------------------------------------------
/// Tests whether two texture images are equal. It might in some rare cases not detect the difference
/// but to make the comparison fast only some sampling points are used. If both pointers are NULL,
/// they are considered equal.
//--------------------------------------------------------------------------------------------------
bool ScalarMapperEffectGenerator : : isImagesEqual ( const cvf : : TextureImage * texImg1 , const cvf : : TextureImage * texImg2 )
{
if ( texImg1 = = NULL & & texImg2 = = NULL ) return true ;
if ( texImg1 ! = NULL & & texImg2 ! = NULL
& & texImg1 - > height ( ) = = texImg2 - > height ( )
& & texImg1 - > width ( ) = = texImg2 - > width ( )
& & texImg1 - > width ( ) > 0 & & texImg1 - > height ( ) > 0
& & texImg1 - > pixel ( 0 , 0 ) = = texImg2 - > pixel ( 0 , 0 )
& & texImg1 - > pixel ( texImg1 - > width ( ) - 1 , texImg1 - > height ( ) - 1 ) = = texImg2 - > pixel ( texImg1 - > width ( ) - 1 , texImg1 - > height ( ) - 1 )
& & texImg1 - > pixel ( texImg1 - > width ( ) / 2 , texImg1 - > height ( ) / 2 ) = = texImg2 - > pixel ( texImg1 - > width ( ) / 2 , texImg1 - > height ( ) / 2 )
& & texImg1 - > pixel ( texImg1 - > width ( ) / 4 , texImg1 - > height ( ) / 4 ) = = texImg2 - > pixel ( texImg1 - > width ( ) / 4 , texImg1 - > height ( ) / 4 )
& & texImg1 - > pixel ( texImg1 - > width ( ) / 2 + texImg1 - > width ( ) / 4 , texImg1 - > height ( ) / 2 + texImg1 - > height ( ) / 4 ) = = texImg2 - > pixel ( texImg1 - > width ( ) / 2 + texImg1 - > width ( ) / 4 , texImg1 - > height ( ) / 2 + texImg1 - > height ( ) / 4 )
)
{
return true ;
}
return false ;
}
2012-05-18 02:45:23 -05:00
//==================================================================================================
//
// ScalarMapperMeshEffectGenerator
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ScalarMapperMeshEffectGenerator : : ScalarMapperMeshEffectGenerator ( const cvf : : ScalarMapper * scalarMapper )
: m_undefinedColor ( cvf : : Color3 : : GRAY )
{
m_scalarMapper = scalarMapper ;
m_opacityLevel = 1.0f ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ScalarMapperMeshEffectGenerator : : updateForShaderBasedRendering ( cvf : : Effect * effect ) const
{
cvf : : ref < cvf : : Effect > eff = effect ;
cvf : : ShaderProgramGenerator gen ( " ScalarMapperMeshEffectGenerator " , cvf : : ShaderSourceProvider : : instance ( ) ) ;
gen . addVertexCode ( cvf : : ShaderSourceRepository : : vs_Standard ) ;
gen . addFragmentCode ( cvf : : ShaderSourceRepository : : src_Texture ) ;
gen . addFragmentCode ( cvf : : ShaderSourceRepository : : fs_Unlit ) ;
cvf : : ref < cvf : : ShaderProgram > prog = gen . generate ( ) ;
eff - > setShaderProgram ( prog . p ( ) ) ;
// Result mapping texture
2012-08-31 12:12:47 -05:00
m_textureImage = new cvf : : TextureImage ;
m_scalarMapper - > updateTexture ( m_textureImage . p ( ) ) ;
2012-05-18 02:45:23 -05:00
2012-08-31 12:12:47 -05:00
cvf : : ref < cvf : : TextureImage > modTexImg = ScalarMapperEffectGenerator : : addAlphaAndUndefStripes ( m_textureImage . p ( ) , m_undefinedColor , m_opacityLevel ) ;
2012-05-18 02:45:23 -05:00
cvf : : ref < cvf : : Texture > texture = new cvf : : Texture ( modTexImg . p ( ) ) ;
cvf : : ref < cvf : : Sampler > sampler = new cvf : : Sampler ;
sampler - > setWrapMode ( cvf : : Sampler : : CLAMP_TO_EDGE ) ;
sampler - > setMinFilter ( cvf : : Sampler : : NEAREST ) ;
sampler - > setMagFilter ( cvf : : Sampler : : NEAREST ) ;
2012-10-02 03:17:52 -05:00
cvf : : ref < cvf : : RenderStateTextureBindings > texBind = new cvf : : RenderStateTextureBindings ;
2012-05-18 02:45:23 -05:00
texBind - > addBinding ( texture . p ( ) , sampler . p ( ) , " u_texture2D " ) ;
eff - > setRenderState ( texBind . p ( ) ) ;
// Hardware independent:
updateCommonEffect ( eff . p ( ) ) ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ScalarMapperMeshEffectGenerator : : updateForFixedFunctionRendering ( cvf : : Effect * effect ) const
{
cvf : : ref < cvf : : Effect > eff = effect ;
2012-10-02 03:17:52 -05:00
eff - > setRenderState ( new cvf : : RenderStateMaterial_FF ( cvf : : Color3 : : WHITE ) ) ;
eff - > setRenderState ( new cvf : : RenderStatePolygonMode ( cvf : : RenderStatePolygonMode : : LINE ) ) ;
eff - > setRenderState ( new cvf : : RenderStateDepth ( true , cvf : : RenderStateDepth : : LEQUAL ) ) ;
eff - > setRenderState ( new cvf : : RenderStateLighting_FF ( false ) ) ;
2012-05-18 02:45:23 -05:00
// Result mapping texture
2012-08-31 12:12:47 -05:00
m_textureImage = new cvf : : TextureImage ;
m_scalarMapper - > updateTexture ( m_textureImage . p ( ) ) ;
2012-05-18 02:45:23 -05:00
2012-08-31 12:12:47 -05:00
cvf : : ref < cvf : : TextureImage > modTexImg = ScalarMapperEffectGenerator : : addAlphaAndUndefStripes ( m_textureImage . p ( ) , m_undefinedColor , m_opacityLevel ) ;
2012-05-18 02:45:23 -05:00
cvf : : ref < cvf : : Texture2D_FF > texture = new cvf : : Texture2D_FF ( modTexImg . p ( ) ) ;
texture - > setWrapMode ( cvf : : Texture2D_FF : : CLAMP ) ;
texture - > setMinFilter ( cvf : : Texture2D_FF : : NEAREST ) ;
texture - > setMagFilter ( cvf : : Texture2D_FF : : NEAREST ) ;
2012-10-02 03:17:52 -05:00
cvf : : ref < cvf : : RenderStateTextureMapping_FF > texMapping = new cvf : : RenderStateTextureMapping_FF ( texture . p ( ) ) ;
texMapping - > setTextureFunction ( cvf : : RenderStateTextureMapping_FF : : DECAL ) ;
2012-05-18 02:45:23 -05:00
eff - > setRenderState ( texMapping . p ( ) ) ;
// Hardware independent:
updateCommonEffect ( eff . p ( ) ) ;
}
//--------------------------------------------------------------------------------------------------
/// It also modifies the texture, and adds two more pixel lines
/// one with a transparent version of the legend color, and one with color for undefined values
//--------------------------------------------------------------------------------------------------
void ScalarMapperMeshEffectGenerator : : updateCommonEffect ( cvf : : Effect * effect ) const
{
CVF_ASSERT ( effect ) ;
// Simple transparency
if ( m_opacityLevel < 1.0f )
{
2012-10-02 03:17:52 -05:00
cvf : : ref < cvf : : RenderStateBlending > blender = new cvf : : RenderStateBlending ;
2012-05-18 02:45:23 -05:00
blender - > configureTransparencyBlending ( ) ;
effect - > setRenderState ( blender . p ( ) ) ;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool ScalarMapperMeshEffectGenerator : : isEqual ( const EffectGenerator * other ) const
{
const ScalarMapperMeshEffectGenerator * otherTextureResultEffect = dynamic_cast < const ScalarMapperMeshEffectGenerator * > ( other ) ;
if ( otherTextureResultEffect )
{
if ( m_scalarMapper . p ( ) = = otherTextureResultEffect - > m_scalarMapper
& & m_opacityLevel = = otherTextureResultEffect - > m_opacityLevel
& & m_undefinedColor = = otherTextureResultEffect - > m_undefinedColor )
{
2012-08-31 12:12:47 -05:00
cvf : : ref < cvf : : TextureImage > texImg2 = new cvf : : TextureImage ;
otherTextureResultEffect - > m_scalarMapper - > updateTexture ( texImg2 . p ( ) ) ;
return ScalarMapperEffectGenerator : : isImagesEqual ( m_textureImage . p ( ) , texImg2 . p ( ) ) ;
2012-05-18 02:45:23 -05:00
}
}
return false ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
EffectGenerator * ScalarMapperMeshEffectGenerator : : copy ( ) const
{
ScalarMapperMeshEffectGenerator * scEffGen = new ScalarMapperMeshEffectGenerator ( m_scalarMapper . p ( ) ) ;
2012-08-31 12:12:47 -05:00
scEffGen - > m_textureImage = m_textureImage ;
2012-05-18 02:45:23 -05:00
scEffGen - > m_opacityLevel = m_opacityLevel ;
scEffGen - > m_undefinedColor = m_undefinedColor ;
return scEffGen ;
}
//==================================================================================================
//
// MeshEffectGenerator
//
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
MeshEffectGenerator : : MeshEffectGenerator ( const cvf : : Color3f & color )
{
m_color = color ;
2015-07-29 07:19:43 -05:00
m_lineStipple = false ;
2017-02-28 11:41:16 -06:00
m_lineWidth = cvf : : UNDEFINED_FLOAT ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void MeshEffectGenerator : : setLineWidth ( float lineWidth )
{
m_lineWidth = lineWidth ;
2012-05-18 02:45:23 -05:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void MeshEffectGenerator : : updateForShaderBasedRendering ( cvf : : Effect * effect ) const
{
cvf : : ShaderProgramGenerator spGen ( " Mesh " , cvf : : ShaderSourceProvider : : instance ( ) ) ;
spGen . addVertexCode ( cvf : : ShaderSourceRepository : : vs_Standard ) ;
spGen . addFragmentCode ( cvf : : ShaderSourceRepository : : src_Color ) ;
spGen . addFragmentCode ( cvf : : ShaderSourceRepository : : fs_Unlit ) ;
cvf : : ref < cvf : : ShaderProgram > shaderProg = spGen . generate ( ) ;
cvf : : ref < cvf : : Effect > eff = effect ;
eff - > setShaderProgram ( shaderProg . p ( ) ) ;
eff - > setUniform ( new cvf : : UniformFloat ( " u_color " , cvf : : Color4f ( m_color , 1.0 ) ) ) ;
2015-07-29 07:19:43 -05:00
if ( m_lineStipple )
{
2015-08-13 08:43:17 -05:00
// TODO: Use when VizFwk is updated
2015-07-29 07:19:43 -05:00
//eff->setRenderState(new cvf::RenderStateLineStipple_FF);
}
2017-02-28 11:41:16 -06:00
if ( m_lineWidth < cvf : : UNDEFINED_FLOAT )
{
2017-02-28 11:48:33 -06:00
eff - > setRenderState ( new cvf : : RenderStateLine ( m_lineWidth ) ) ;
2017-02-28 11:41:16 -06:00
}
2017-03-08 07:27:02 -06:00
eff - > setRenderState ( new cvf : : RenderStateDepth ( true , cvf : : RenderStateDepth : : LEQUAL ) ) ;
2012-05-18 02:45:23 -05:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void MeshEffectGenerator : : updateForFixedFunctionRendering ( cvf : : Effect * effect ) const
{
cvf : : ref < cvf : : Effect > eff = effect ;
2012-10-02 03:17:52 -05:00
eff - > setRenderState ( new cvf : : RenderStateMaterial_FF ( m_color ) ) ;
eff - > setRenderState ( new cvf : : RenderStatePolygonMode ( cvf : : RenderStatePolygonMode : : LINE ) ) ;
eff - > setRenderState ( new cvf : : RenderStateDepth ( true , cvf : : RenderStateDepth : : LEQUAL ) ) ;
eff - > setRenderState ( new cvf : : RenderStateLighting_FF ( false ) ) ;
2012-05-18 02:45:23 -05:00
2015-07-29 07:19:43 -05:00
if ( m_lineStipple )
{
2015-08-13 08:43:17 -05:00
// TODO: Use when VizFwk is updated
2015-07-29 07:19:43 -05:00
//eff->setRenderState(new cvf::RenderStateLineStipple_FF);
}
2012-05-18 02:45:23 -05:00
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool MeshEffectGenerator : : isEqual ( const EffectGenerator * other ) const
{
const MeshEffectGenerator * otherMesh = dynamic_cast < const MeshEffectGenerator * > ( other ) ;
if ( otherMesh )
{
2015-07-29 07:19:43 -05:00
if ( m_color ! = otherMesh - > m_color )
2012-05-18 02:45:23 -05:00
{
2015-07-29 07:19:43 -05:00
return false ;
}
if ( m_lineStipple ! = otherMesh - > m_lineStipple )
{
return false ;
2012-05-18 02:45:23 -05:00
}
2015-07-29 07:19:43 -05:00
2017-02-28 11:41:16 -06:00
if ( m_lineWidth ! = otherMesh - > m_lineWidth )
{
return false ;
}
2015-07-29 07:19:43 -05:00
return true ;
2012-05-18 02:45:23 -05:00
}
return false ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
EffectGenerator * MeshEffectGenerator : : copy ( ) const
{
2015-07-29 07:19:43 -05:00
MeshEffectGenerator * effGen = new MeshEffectGenerator ( m_color ) ;
effGen - > setLineStipple ( m_lineStipple ) ;
2017-02-28 11:41:16 -06:00
effGen - > setLineWidth ( m_lineWidth ) ;
2015-07-29 07:19:43 -05:00
return effGen ;
2012-05-18 02:45:23 -05:00
}
2015-11-17 09:26:07 -06:00
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TextEffectGenerator : : TextEffectGenerator ( )
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool TextEffectGenerator : : isEqual ( const EffectGenerator * other ) const
{
const TextEffectGenerator * otherSurfaceEffect = dynamic_cast < const TextEffectGenerator * > ( other ) ;
if ( otherSurfaceEffect )
{
return true ;
}
return false ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
EffectGenerator * TextEffectGenerator : : copy ( ) const
{
TextEffectGenerator * effGen = new TextEffectGenerator ;
return effGen ;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void TextEffectGenerator : : updateForShaderBasedRendering ( cvf : : Effect * effect ) const
{
// See OpenGLResourceManager::getLinkedTextShaderProgram for code to be used here
// Detected some issues on RHEL 6 related to text, so use an empty effect for now
// Will fall back to fixed function rendering
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void TextEffectGenerator : : updateForFixedFunctionRendering ( cvf : : Effect * effect ) const
{
}
2012-05-18 02:45:23 -05:00
} // End namespace caf