Upgraded visualization libraries

Major refactoring of color legend framework
Added discrete log color legend
p4#: 18989
This commit is contained in:
Magne Sjaastad 2012-10-02 10:17:52 +02:00
parent 082560b2a5
commit 9c1ce7591e
163 changed files with 8917 additions and 3214 deletions

View File

@ -23,7 +23,7 @@
#include "cvfObject.h"
#include "cvfScalarMapperUniformLevels.h"
#include "cvfOverlayColorLegend.h"
#include "cvfOverlayScalarMapperLegend.h"
#include "RimReservoirView.h"
#include <iostream>

View File

@ -32,16 +32,16 @@ include_directories(
# variable you can point to a different ERT distribution.
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(ERT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert" CACHE DIRECTORY "Root path for ERT installation to build against")
set(ERT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert")
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
if (CMAKE_CL_64)
set(ERT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert-windows-x64" CACHE DIRECTORY "Root path for ERT installation to build against")
set(ERT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert-windows-x64")
else()
set(ERT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert-windows" CACHE DIRECTORY "Root path for ERT installation to build against")
set(ERT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert-windows")
endif()
endif()
# The ERT binary distribution consists of four libraries, libwell, libecl,
# libutil and libgeometry and their accompanying header files. There has been a
# bit of mess of how this has been organized; either it has been on per
@ -94,7 +94,7 @@ endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
list(APPEND ERT_LIBRARY_LIST lapack z)
endif()
endif()
include_directories( ${ERT_INCLUDE_LIST} )
# Ert configuration complete
@ -128,7 +128,7 @@ list( APPEND CPP_SOURCES
)
list( APPEND CPP_SOURCES
FileInterface/RifEclipseInputFileTools.cpp
FileInterface/RifEclipseInputFileTools.cpp
FileInterface/RifEclipseOutputFileTools.cpp
FileInterface/RifEclipseRestartFilesetAccess.cpp
FileInterface/RifEclipseRestartDataAccess.cpp
@ -206,7 +206,7 @@ set ( QT_MOC_HEADERS
UserInterface/RIResultInfoPanel.h
UserInterface/RIViewer.h
UserInterface/RIProcessMonitor.h
SocketInterface/RiaSocketServer.h
SocketInterface/RiaSocketServer.h
)
qt4_wrap_cpp( MOC_FILES_CPP ${QT_MOC_HEADERS} )
@ -279,7 +279,7 @@ add_executable(ResInsight
${CPP_SOURCES}
${MOC_FILES_CPP}
${QRC_FILES_CPP}
${HEADER_FILES}
${HEADER_FILES}
)
@ -299,6 +299,15 @@ set( LINK_LIBRARIES
${QT_LIBRARIES}
)
set( EXTERNAL_LINK_LIBRARIES ${ERT_LIBRARY_LIST} )
# According to ivarun this is needed on OpenSuse, and Fedora. See: https://github.com/OPM/ResInsight/pull/7
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set ( EXTERNAL_LINK_LIBRARIES
${EXTERNAL_LINK_LIBRARIES}
rt
)
endif()
target_link_libraries( ResInsight ${LINK_LIBRARIES} ${EXTERNAL_LINK_LIBRARIES})
# Copy Dlls
@ -378,8 +387,8 @@ IF(${CMAKE_SYSTEM_NAME} MATCHES "No_Linux")
install(CODE "
set (INSTALLFILE_LIST
${CMAKE_CURRENT_BINARY_DIR}/ResInsight
${CMAKE_CURRENT_SOURCE_DIR}/Adm/LicenseInformation.txt
${CMAKE_CURRENT_SOURCE_DIR}/Adm/gplLicense.txt
${CMAKE_CURRENT_SOURCE_DIR}/Adm/LicenseInformation.txt
${CMAKE_CURRENT_SOURCE_DIR}/Adm/gplLicense.txt
${QT_LIBRARY_DIR}/libQtCore.so.4
${QT_LIBRARY_DIR}/libQtGui.so.4
${QT_LIBRARY_DIR}/libQtOpenGL.so.4

View File

@ -25,18 +25,17 @@ include_directories(
)
#-----------------------------------------------------------------
# Ert configuration
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set(ERT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert" CACHE DIRECTORY "Root path for ERT installation to build against")
set(ERT_ROOT_PATH "${ResInsight_SOURCE_DIR}/ThirdParty/Ert")
elseif (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
if (CMAKE_CL_64)
set(ERT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert-windows-x64" CACHE DIRECTORY "Root path for ERT installation to build against")
set(ERT_ROOT_PATH "${ResInsight_SOURCE_DIR}/ThirdParty/Ert-windows-x64")
else()
set(ERT_ROOT_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../ThirdParty/Ert-windows" CACHE DIRECTORY "Root path for ERT installation to build against")
set(ERT_ROOT_PATH "${ResInsight_SOURCE_DIR}/ThirdParty/Ert-windows")
endif()
endif()
set( ERT_ECL_PREFIX "ecl" CACHE STRING "Prefix path to use for ecl code in ert")
set( ERT_UTIL_PREFIX "util" CACHE STRING "Prefix path to use for util code in ert")
set( ERT_WELL_PREFIX "well" CACHE STRING "Prefix path to use for well code in ert")
@ -64,7 +63,7 @@ endif()
if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
list(APPEND ERT_LIBRARY_LIST lapack z)
endif()
endif()
#-----------------------------------------------------------------
include_directories( ${ERT_INCLUDE_LIST} )

View File

@ -31,6 +31,7 @@
#include "cvfShaderSourceProvider.h"
#include "cvfqtUtils.h"
#include "cvfShaderProgram.h"
#include "cvfRenderStateCullFace.h"
#include <vector>
#include <QFile>
@ -314,7 +315,7 @@ void CellEdgeEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect)
}
}
shaderGen.addFragmentCode(cvf::ShaderSourceRepository::light_AmbientDiffuse);
shaderGen.addFragmentCode(caf::CommonShaderSources::light_AmbientDiffuse());
shaderGen.addFragmentCode(cvf::ShaderSourceRepository::fs_Standard);
cvf::ref<cvf::ShaderProgram> prog = shaderGen.generate();
@ -347,7 +348,7 @@ void CellEdgeEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect)
sampler->setMinFilter(cvf::Sampler::NEAREST);
sampler->setMagFilter(cvf::Sampler::NEAREST);
cvf::ref<cvf::TextureBindings> texBind = new cvf::TextureBindings;
cvf::ref<cvf::RenderStateTextureBindings> texBind = new cvf::RenderStateTextureBindings;
texBind->addBinding(edgeTexture.p(), sampler.p(), "u_edgeTexture2D");
texBind->addBinding(cellTexture.p(), sampler.p(), "u_cellTexture2D");
eff->setRenderState(texBind.p());
@ -356,7 +357,7 @@ void CellEdgeEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect)
if (true)
{
cvf::ref<cvf::PolygonOffset> polyOffset = new cvf::PolygonOffset;
cvf::ref<cvf::RenderStatePolygonOffset> polyOffset = new cvf::RenderStatePolygonOffset;
polyOffset->configurePolygonPositiveOffset();
eff->setRenderState(polyOffset.p());
}
@ -364,7 +365,7 @@ void CellEdgeEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect)
// Simple transparency
if (m_opacityLevel < 1.0f)
{
cvf::ref<cvf::Blending> blender = new cvf::Blending;
cvf::ref<cvf::RenderStateBlending> blender = new cvf::RenderStateBlending;
blender->configureTransparencyBlending();
eff->setRenderState(blender.p());
}
@ -373,7 +374,7 @@ void CellEdgeEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect)
if (m_cullBackfaces)
{
cvf::ref<cvf::CullFace> faceCulling = new cvf::CullFace;
cvf::ref<cvf::RenderStateCullFace> faceCulling = new cvf::RenderStateCullFace;
eff->setRenderState(faceCulling.p());
}
}

View File

@ -35,7 +35,7 @@ public:
RivReservoirViewPartMgr(RimReservoirView * resv);
cvf::Transform* scaleTransform() { return m_scaleTransform.p();}
void setScaleTransform(cvf::Mat4d scale) { m_scaleTransform->setWorldTransform(scale);}
void setScaleTransform(cvf::Mat4d scale) { m_scaleTransform->setLocalTransform(scale);}
enum ReservoirGeometryCacheType
{

View File

@ -52,7 +52,7 @@ RivWellPipesPartMgr::RivWellPipesPartMgr(RimReservoirView* reservoirView, RimWel
legendColors[3] = cvf::Color3::RED;
scalarMapper->setColors(legendColors);
scalarMapper->setRange(0.0 , 4.0);
scalarMapper->setLevelsFromColorCount(4);
scalarMapper->setLevelCount(4, true);
m_scalarMapper = scalarMapper;

View File

@ -23,6 +23,7 @@
#include "cafFactory.h"
#include "cafPdmUiLineEditor.h"
#include "cafPdmUiComboBoxEditor.h"
#include "cvfScalarMapperDiscreteLog.h"
CAF_PDM_SOURCE_INIT(RimLegendConfig, "Legend");
@ -58,6 +59,7 @@ namespace caf {
addItem(RimLegendConfig::LINEAR_DISCRETE, "LinearDiscrete", "Discrete Linear");
addItem(RimLegendConfig::LINEAR_CONTINUOUS, "LinearContinuous", "Continuous Linear");
addItem(RimLegendConfig::LOG10_CONTINUOUS, "Log10Continuous", "Continuous Logarithmic");
addItem(RimLegendConfig::LOG10_DISCRETE, "Log10Discrete", "Discrete Logarithmic");
setDefault(RimLegendConfig::LINEAR_CONTINUOUS);
}
}
@ -83,17 +85,16 @@ RimLegendConfig::RimLegendConfig()
CAF_PDM_InitField(&resultVariableName, "ResultVariableUsage", QString(""), "", "", "", "");
resultVariableName.setUiHidden(true);
m_linDiscreteScalarMapper = new cvf::ScalarMapperUniformLevels;
m_linDiscreteScalarMapper->setTextureSize(1024);
m_logSmoothScalarMapper = new cvf::ScalarMapperContinuousLog;
m_linDiscreteScalarMapper = new cvf::ScalarMapperDiscreteLinear;
m_logDiscreteScalarMapper = new cvf::ScalarMapperDiscreteLog;
m_linSmoothScalarMapper = new cvf::ScalarMapperContinuousLinear;
m_logSmoothScalarMapper = new cvf::ScalarMapperContinuousLog;
m_currentScalarMapper = m_linDiscreteScalarMapper;
cvf::FixedAtlasFont* font = new cvf::FixedAtlasFont(cvf::FixedAtlasFont::STANDARD);
m_legend = new cvf::OverlayColorLegend(font);
m_legend = new cvf::OverlayScalarMapperLegend(font);
m_position = cvf::Vec2ui(20, 50);
updateFieldVisibility();
@ -164,7 +165,9 @@ void RimLegendConfig::updateLegend()
adjustedMax = adjust(m_userDefinedMaxValue, m_precision);
}
m_linDiscreteScalarMapper->setRange(adjustedMin, adjustedMax);
m_logDiscreteScalarMapper->setRange(adjustedMin, adjustedMax);
m_logSmoothScalarMapper->setRange(adjustedMin, adjustedMax);
m_linSmoothScalarMapper->setRange(adjustedMin, adjustedMax);
@ -173,26 +176,26 @@ void RimLegendConfig::updateLegend()
{
case NORMAL:
{
legendColors.reserve(5);
legendColors.reserve(7);
legendColors.add(cvf::Color3ub( 0, 0, 255));
legendColors.add(cvf::Color3ub( 0, 127, 255));
legendColors.add(cvf::Color3ub( 0, 255, 255));
legendColors.add(cvf::Color3ub( 0, 255, 0));
legendColors.add(cvf::Color3ub(255, 255, 0));
legendColors.add(cvf::Color3ub(255, 127, 0));
legendColors.add(cvf::Color3ub(255, 0, 0));
m_linDiscreteScalarMapper->setColors(cvf::ScalarMapper::NORMAL, m_numLevels);
}
break;
case OPPOSITE_NORMAL:
{
legendColors.reserve(5);
legendColors.reserve(7);
legendColors.add(cvf::Color3ub(255, 0, 0));
legendColors.add(cvf::Color3ub(255, 127, 0));
legendColors.add(cvf::Color3ub(255, 255, 0));
legendColors.add(cvf::Color3ub( 0, 255, 0));
legendColors.add(cvf::Color3ub( 0, 255, 255));
legendColors.add(cvf::Color3ub( 0, 127, 255));
legendColors.add(cvf::Color3ub( 0, 0, 255));
m_linDiscreteScalarMapper->setColors(legendColors); // Todo: Change legend type to new
}
break; case BLACK_WHITE:
case WHITE_BLACK:
@ -208,8 +211,6 @@ void RimLegendConfig::updateLegend()
legendColors.add(cvf::Color3ub::WHITE);
legendColors.add(cvf::Color3ub::BLACK);
}
cvf::ref<cvf::Color3ubArray> interpolated = interpolateColorArray(legendColors, m_numLevels);
m_linDiscreteScalarMapper->setColors(*(interpolated.p()));
}
break;
case PINK_WHITE:
@ -226,17 +227,19 @@ void RimLegendConfig::updateLegend()
legendColors.add(cvf::Color3ub::WHITE);
legendColors.add(cvf::Color3ub::DEEP_PINK);
}
cvf::ref<cvf::Color3ubArray> interpolated = interpolateColorArray(legendColors, m_numLevels);
m_linDiscreteScalarMapper->setColors(*(interpolated.p()));
}
break;
}
m_linDiscreteScalarMapper->setColors(legendColors);
m_logDiscreteScalarMapper->setColors(legendColors);
m_logSmoothScalarMapper->setColors(legendColors);
m_linSmoothScalarMapper->setColors(legendColors);
m_logSmoothScalarMapper->setMajorLevelCount(m_numLevels, true);
m_linSmoothScalarMapper->setMajorLevelCount(m_numLevels, true);
m_linDiscreteScalarMapper->setLevelCount(m_numLevels, true);
m_logDiscreteScalarMapper->setLevelCount(m_numLevels, true);
m_logSmoothScalarMapper->setLevelCount(m_numLevels, true);
m_linSmoothScalarMapper->setLevelCount(m_numLevels, true);
switch(m_mappingMode())
{
@ -249,9 +252,13 @@ void RimLegendConfig::updateLegend()
case LOG10_CONTINUOUS:
m_currentScalarMapper = m_logSmoothScalarMapper.p();
break;
case LOG10_DISCRETE:
m_currentScalarMapper = m_logDiscreteScalarMapper.p();
break;
default:
break;
}
m_legend->setScalarMapper(m_currentScalarMapper.p());
@ -322,6 +329,7 @@ void RimLegendConfig::setColorRangeMode(ColorRangesType colorMode)
updateLegend();
}
/*
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -367,7 +375,7 @@ cvf::ref<cvf::Color3ubArray> RimLegendConfig::interpolateColorArray(const cvf::C
return colors;
}
*/
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -387,7 +395,7 @@ void RimLegendConfig::recreateLegend()
// the legend disappeared because of this, so workaround: recreate the legend when needed:
cvf::FixedAtlasFont* font = new cvf::FixedAtlasFont(cvf::FixedAtlasFont::STANDARD);
m_legend = new cvf::OverlayColorLegend(font);
m_legend = new cvf::OverlayScalarMapperLegend(font);
updateLegend();
}

View File

@ -24,8 +24,8 @@
#include "cafAppEnum.h"
#include "cvfScalarMapperContinuousLog.h"
#include "cvfScalarMapperContinuousLinear.h"
#include "cvfOverlayColorLegend.h"
#include "cvfScalarMapperUniformLevels.h"
#include "cvfOverlayScalarMapperLegend.h"
#include "cvfScalarMapperDiscreteLinear.h"
class RimReservoirView;
//==================================================================================================
@ -66,7 +66,8 @@ public:
{
LINEAR_DISCRETE,
LINEAR_CONTINUOUS,
LOG10_CONTINUOUS
LOG10_CONTINUOUS,
LOG10_DISCRETE
};
typedef caf::AppEnum<MappingType> MappingEnum;
@ -76,7 +77,7 @@ public:
void setPosition(cvf::Vec2ui position);
cvf::ScalarMapper* scalarMapper() { return m_currentScalarMapper.p(); }
cvf::OverlayColorLegend* legend() { return m_legend.p(); }
cvf::OverlayScalarMapperLegend* legend() { return m_legend.p(); }
void updateLegend();
protected:
@ -90,12 +91,13 @@ private:
private:
caf::PdmPointer<RimReservoirView> m_reservoirView;
cvf::ref<cvf::ScalarMapperUniformLevels> m_linDiscreteScalarMapper;
cvf::ref<cvf::ScalarMapperDiscreteLinear> m_linDiscreteScalarMapper;
cvf::ref<cvf::ScalarMapperDiscreteLinear> m_logDiscreteScalarMapper;
cvf::ref<cvf::ScalarMapperContinuousLog> m_logSmoothScalarMapper;
cvf::ref<cvf::ScalarMapperContinuousLinear> m_linSmoothScalarMapper;
cvf::ref<cvf::LegendScalarMapper> m_currentScalarMapper;
cvf::ref<cvf::ScalarMapper> m_currentScalarMapper;
cvf::ref<cvf::OverlayColorLegend> m_legend;
cvf::ref<cvf::OverlayScalarMapperLegend> m_legend;
double m_globalAutoMax;
double m_globalAutoMin;

View File

@ -120,7 +120,7 @@ RIViewer::~RIViewer()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RIViewer::setColorLegend1(cvf::OverlayColorLegend* legend)
void RIViewer::setColorLegend1(cvf::OverlayScalarMapperLegend* legend)
{
m_mainRendering->removeOverlayItem(m_legend1.p());
@ -133,7 +133,7 @@ void RIViewer::setColorLegend1(cvf::OverlayColorLegend* legend)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RIViewer::setColorLegend2(cvf::OverlayColorLegend* legend)
void RIViewer::setColorLegend2(cvf::OverlayScalarMapperLegend* legend)
{
m_mainRendering->removeOverlayItem(m_legend2.p());

View File

@ -48,8 +48,8 @@ public:
RIViewer(const QGLFormat& format, QWidget* parent);
~RIViewer();
void setColorLegend1(cvf::OverlayColorLegend* legend);
void setColorLegend2(cvf::OverlayColorLegend* legend);
void setColorLegend1(cvf::OverlayScalarMapperLegend* legend);
void setColorLegend2(cvf::OverlayScalarMapperLegend* legend);
void setDefaultView();
cvf::Vec3d pointOfInterest();
void setPointOfInterest(cvf::Vec3d poi);
@ -90,8 +90,8 @@ private:
cvf::ref<cvf::OverlayColorLegend> m_legend1;
cvf::ref<cvf::OverlayColorLegend> m_legend2;
cvf::ref<cvf::OverlayScalarMapperLegend> m_legend1;
cvf::ref<cvf::OverlayScalarMapperLegend> m_legend2;
caf::PdmPointer<RimReservoirView> m_reservoirView;

View File

@ -30,6 +30,12 @@
#include "cvfMatrixState.h"
#include "cvfTexture.h"
#include "cvfSampler.h"
#include "cvfRenderStatePolygonOffset.h"
#include "cvfRenderStateBlending.h"
#include "cvfRenderStateCullFace.h"
#include "cvfRenderStateTextureBindings.h"
#include "cvfRenderStatePolygonMode.h"
#include "cvfRenderStateDepth.h"
#include <QtOpenGL/QGLFormat>
#include "cafEffectCache.h"
@ -37,6 +43,49 @@
namespace caf {
//#############################################################################################################################
//#############################################################################################################################
static const char light_AmbientDiffuse_inl[] =
" \n"
"varying vec3 v_ecPosition; \n"
"varying vec3 v_ecNormal; \n"
" \n"
"//-------------------------------------------------------------------------------------------------- \n"
"/// lightFragment() - Simple Headlight without Phong/specular component \n"
"/// \n"
"//-------------------------------------------------------------------------------------------------- \n"
"vec4 lightFragment(vec4 srcFragColor, float not_in_use_shadowFactor) \n"
"{ \n"
" const vec3 ecLightPosition = vec3(0.5, 5.0, 7.0); \n"
" const float ambientIntensity = 0.2; \n"
" \n"
" // Light vector (from point to light source) \n"
" vec3 L = normalize(ecLightPosition - v_ecPosition); \n"
" \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);
}
//==================================================================================================
//
// EffectGenerator Base class
@ -164,7 +213,7 @@ void SurfaceEffectGenerator::updateForShaderBasedRendering(cvf::Effect* effect)
cvf::ShaderProgramGenerator gen("SurfaceEffectGenerator", cvf::ShaderSourceProvider::instance());
gen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard);
gen.addFragmentCode(cvf::ShaderSourceRepository::src_Color);
gen.addFragmentCode(cvf::ShaderSourceRepository::light_AmbientDiffuse);
gen.addFragmentCode(CommonShaderSources::light_AmbientDiffuse());
gen.addFragmentCode(cvf::ShaderSourceRepository::fs_Standard);
cvf::ref<cvf::ShaderProgram> shaderProg = gen.generate();
@ -184,12 +233,12 @@ void SurfaceEffectGenerator::updateForFixedFunctionRendering(cvf::Effect* effect
{
cvf::ref<cvf::Effect> eff = effect;
cvf::ref<cvf::Material_FF> mat = new cvf::Material_FF(m_color.toColor3f());
cvf::ref<cvf::RenderStateMaterial_FF> mat = new cvf::RenderStateMaterial_FF(m_color.toColor3f());
mat->setAlpha(m_color.a());
eff->setRenderState(mat.p());
cvf::ref<cvf::Lighting_FF> lighting = new cvf::Lighting_FF;
cvf::ref<cvf::RenderStateLighting_FF> lighting = new cvf::RenderStateLighting_FF;
lighting->enableTwoSided(true);
eff->setRenderState(lighting.p());
@ -204,7 +253,7 @@ void SurfaceEffectGenerator::updateCommonEffect(cvf::Effect* effect) const
{
if (m_polygonOffset)
{
cvf::ref<cvf::PolygonOffset> polyOffset = new cvf::PolygonOffset;
cvf::ref<cvf::RenderStatePolygonOffset> polyOffset = new cvf::RenderStatePolygonOffset;
polyOffset->configurePolygonPositiveOffset();
effect->setRenderState(polyOffset.p());
}
@ -212,7 +261,7 @@ void SurfaceEffectGenerator::updateCommonEffect(cvf::Effect* effect) const
// Simple transparency
if (m_color.a() < 1.0f)
{
cvf::ref<cvf::Blending> blender = new cvf::Blending;
cvf::ref<cvf::RenderStateBlending> blender = new cvf::RenderStateBlending;
blender->configureTransparencyBlending();
effect->setRenderState(blender.p());
}
@ -221,7 +270,7 @@ void SurfaceEffectGenerator::updateCommonEffect(cvf::Effect* effect) const
if (m_cullBackfaces)
{
cvf::ref<cvf::CullFace> faceCulling = new cvf::CullFace;
cvf::ref<cvf::RenderStateCullFace> faceCulling = new cvf::RenderStateCullFace;
effect->setRenderState(faceCulling.p());
}
}
@ -289,7 +338,7 @@ void ScalarMapperEffectGenerator::updateForShaderBasedRendering(cvf::Effect* eff
cvf::ShaderProgramGenerator gen("ScalarMapperEffectGenerator", cvf::ShaderSourceProvider::instance());
gen.addVertexCode(cvf::ShaderSourceRepository::vs_Standard);
gen.addFragmentCode(cvf::ShaderSourceRepository::src_Texture);
gen.addFragmentCode(cvf::ShaderSourceRepository::light_AmbientDiffuse);
gen.addFragmentCode(CommonShaderSources::light_AmbientDiffuse());
gen.addFragmentCode(cvf::ShaderSourceRepository::fs_Standard);
cvf::ref<cvf::ShaderProgram> prog = gen.generate();
@ -308,7 +357,7 @@ void ScalarMapperEffectGenerator::updateForShaderBasedRendering(cvf::Effect* eff
sampler->setMinFilter(cvf::Sampler::NEAREST);
sampler->setMagFilter(cvf::Sampler::NEAREST);
cvf::ref<cvf::TextureBindings> texBind = new cvf::TextureBindings;
cvf::ref<cvf::RenderStateTextureBindings> texBind = new cvf::RenderStateTextureBindings;
texBind->addBinding(texture.p(), sampler.p(), "u_texture2D");
eff->setRenderState(texBind.p());
@ -324,10 +373,10 @@ void ScalarMapperEffectGenerator::updateForFixedFunctionRendering(cvf::Effect* e
{
cvf::ref<cvf::Effect> eff = effect;
cvf::ref<cvf::Material_FF> mat = new cvf::Material_FF(cvf::Color3::WHITE);
cvf::ref<cvf::RenderStateMaterial_FF> mat = new cvf::RenderStateMaterial_FF(cvf::Color3::WHITE);
eff->setRenderState(mat.p());
cvf::ref<cvf::Lighting_FF> lighting = new cvf::Lighting_FF;
cvf::ref<cvf::RenderStateLighting_FF> lighting = new cvf::RenderStateLighting_FF;
lighting->enableTwoSided(true);
eff->setRenderState(lighting.p());
@ -342,7 +391,7 @@ void ScalarMapperEffectGenerator::updateForFixedFunctionRendering(cvf::Effect* e
texture->setWrapMode(cvf::Texture2D_FF::CLAMP);
texture->setMinFilter(cvf::Texture2D_FF::NEAREST);
texture->setMagFilter(cvf::Texture2D_FF::NEAREST);
cvf::ref<cvf::TextureMapping_FF> texMapping = new cvf::TextureMapping_FF(texture.p());
cvf::ref<cvf::RenderStateTextureMapping_FF> texMapping = new cvf::RenderStateTextureMapping_FF(texture.p());
eff->setRenderState(texMapping.p());
// Hardware independent:
@ -361,7 +410,7 @@ void ScalarMapperEffectGenerator::updateCommonEffect(cvf::Effect* effect) const
if (m_polygonOffset)
{
cvf::ref<cvf::PolygonOffset> polyOffset = new cvf::PolygonOffset;
cvf::ref<cvf::RenderStatePolygonOffset> polyOffset = new cvf::RenderStatePolygonOffset;
polyOffset->configurePolygonPositiveOffset();
effect->setRenderState(polyOffset.p());
}
@ -369,7 +418,7 @@ void ScalarMapperEffectGenerator::updateCommonEffect(cvf::Effect* effect) const
// Simple transparency
if (m_opacityLevel < 1.0f)
{
cvf::ref<cvf::Blending> blender = new cvf::Blending;
cvf::ref<cvf::RenderStateBlending> blender = new cvf::RenderStateBlending;
blender->configureTransparencyBlending();
effect->setRenderState(blender.p());
}
@ -378,7 +427,7 @@ void ScalarMapperEffectGenerator::updateCommonEffect(cvf::Effect* effect) const
if (m_cullBackfaces)
{
cvf::ref<cvf::CullFace> faceCulling = new cvf::CullFace;
cvf::ref<cvf::RenderStateCullFace> faceCulling = new cvf::RenderStateCullFace;
effect->setRenderState(faceCulling.p());
}
}
@ -522,7 +571,7 @@ void ScalarMapperMeshEffectGenerator::updateForShaderBasedRendering(cvf::Effect*
sampler->setMinFilter(cvf::Sampler::NEAREST);
sampler->setMagFilter(cvf::Sampler::NEAREST);
cvf::ref<cvf::TextureBindings> texBind = new cvf::TextureBindings;
cvf::ref<cvf::RenderStateTextureBindings> texBind = new cvf::RenderStateTextureBindings;
texBind->addBinding(texture.p(), sampler.p(), "u_texture2D");
eff->setRenderState(texBind.p());
@ -538,10 +587,10 @@ void ScalarMapperMeshEffectGenerator::updateForFixedFunctionRendering(cvf::Effec
{
cvf::ref<cvf::Effect> eff = effect;
eff->setRenderState(new cvf::Material_FF(cvf::Color3::WHITE));
eff->setRenderState(new cvf::PolygonMode(cvf::PolygonMode::LINE));
eff->setRenderState(new cvf::Depth(true, cvf::Depth::LEQUAL));
eff->setRenderState(new cvf::Lighting_FF(false));
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));
// Result mapping texture
@ -555,8 +604,8 @@ void ScalarMapperMeshEffectGenerator::updateForFixedFunctionRendering(cvf::Effec
texture->setMinFilter(cvf::Texture2D_FF::NEAREST);
texture->setMagFilter(cvf::Texture2D_FF::NEAREST);
cvf::ref<cvf::TextureMapping_FF> texMapping = new cvf::TextureMapping_FF(texture.p());
texMapping->setTextureFunction(cvf::TextureMapping_FF::DECAL);
cvf::ref<cvf::RenderStateTextureMapping_FF> texMapping = new cvf::RenderStateTextureMapping_FF(texture.p());
texMapping->setTextureFunction(cvf::RenderStateTextureMapping_FF::DECAL);
eff->setRenderState(texMapping.p());
// Hardware independent:
@ -576,7 +625,7 @@ void ScalarMapperMeshEffectGenerator::updateCommonEffect(cvf::Effect* effect) co
// Simple transparency
if (m_opacityLevel < 1.0f)
{
cvf::ref<cvf::Blending> blender = new cvf::Blending;
cvf::ref<cvf::RenderStateBlending> blender = new cvf::RenderStateBlending;
blender->configureTransparencyBlending();
effect->setRenderState(blender.p());
}
@ -659,10 +708,10 @@ void MeshEffectGenerator::updateForFixedFunctionRendering(cvf::Effect* effect) c
{
cvf::ref<cvf::Effect> eff = effect;
eff->setRenderState(new cvf::Material_FF(m_color));
eff->setRenderState(new cvf::PolygonMode(cvf::PolygonMode::LINE));
eff->setRenderState(new cvf::Depth(true, cvf::Depth::LEQUAL));
eff->setRenderState(new cvf::Lighting_FF(false));
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));
}

View File

@ -25,9 +25,16 @@
#include "cvfScalarMapper.h"
#include "cvfTextureImage.h"
#include "cvfCollection.h"
#include "cvfString.h"
namespace caf {
class CommonShaderSources
{
public:
static cvf::String light_AmbientDiffuse();
};
//==================================================================================================
//

View File

@ -76,13 +76,3 @@ cvfVector4.cpp
add_library(${PROJECT_NAME} ${CEE_HEADER_FILES} ${CEE_SOURCE_FILES})
if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
set ( EXTERNAL_LINK_LIBRARIES
rt
)
endif()
target_link_libraries(LibCore ${EXTERNAL_LINK_LIBRARIES})

View File

@ -174,7 +174,8 @@ namespace cvf {
/// \class cvf::Base64
/// \ingroup Core
///
///
/// Base64 encoding and decoding for representing binary data in an ASCII string format by
/// translating it into a radix-64 representation.
///
//==================================================================================================

View File

@ -27,16 +27,14 @@ namespace cvf {
//==================================================================================================
//
// Base64 encoding and decoding for representing binary data in an ASCII string format by
// translating it into a radix-64 representation.
// Base64 encoding and decoding for representing binary data in an ASCII string
//
//==================================================================================================
class Base64
{
public:
static std::string encode(const cvf::UByteArray& data);
static cvf::ref<cvf::UByteArray> decode(const std::string& encodedData);
static std::string encode(const cvf::UByteArray& data);
static cvf::ref<cvf::UByteArray> decode(const std::string& encodedData);
};
}

View File

@ -39,12 +39,15 @@ public:
Matrix3(S m00, S m01, S m02, S m10, S m11, S m12, S m20, S m21, S m22);
template<typename T>
explicit Matrix3(const T& other);
explicit Matrix3(const Matrix3<T>& other);
inline Matrix3& operator=(const Matrix3& rhs);
bool equals(const Matrix3& mat) const;
bool operator==(const Matrix3& rhs) const;
bool operator!=(const Matrix3& rhs) const;
void multiply(const Matrix3& mat);
const Matrix3 operator*(const Matrix3& rhs) const;
void setIdentity();
@ -52,10 +55,10 @@ public:
void setZero();
bool isZero() const;
inline S& operator()(int row, int col);
inline S operator()(int row, int col) const;
inline void setRowCol(int row, int col, S value);
inline S rowCol(int row, int col) const;
inline S& operator()(int row, int col);
inline S operator()(int row, int col) const;
bool invert();
const Matrix3 getInverted(bool* pInvertible = NULL) const;

View File

@ -89,7 +89,7 @@ Matrix3<S>::Matrix3(S m00, S m01, S m02, S m10, S m11, S m12, S m20, S m21, S m2
//----------------------------------------------------------------------------------------------------
template<typename S>
template<typename T>
Matrix3<S>::Matrix3(const T& other)
Matrix3<S>::Matrix3(const Matrix3<T>& other)
{
m_v[e00] = static_cast<S>(other.rowCol(0, 0));
m_v[e01] = static_cast<S>(other.rowCol(0, 1));
@ -114,19 +114,28 @@ inline Matrix3<S>& Matrix3<S>::operator=(const Matrix3& obj)
}
//----------------------------------------------------------------------------------------------------
/// Check if matrices are equal using exact comparisons.
//----------------------------------------------------------------------------------------------------
template<typename S>
bool Matrix3<S>::equals(const Matrix3& mat) const
{
for (int i = 0; i < 9; i++)
{
if (m_v[i] != mat.m_v[i]) return false;
}
return true;
}
//----------------------------------------------------------------------------------------------------
/// Comparison operator. Checks for equality using exact comparisons.
//----------------------------------------------------------------------------------------------------
template <typename S>
bool Matrix3<S>::operator==(const Matrix3& rhs) const
{
int i;
for (i = 0; i < 9; i++)
{
if (m_v[i] != rhs.m_v[i]) return false;
}
return true;
return this->equals(rhs);
}
@ -146,6 +155,16 @@ bool Matrix3<S>::operator!=(const Matrix3& rhs) const
}
//--------------------------------------------------------------------------------------------------
/// Multiplies this matrix M with the matrix \a mat, M = M*mat
//--------------------------------------------------------------------------------------------------
template<typename S>
void Matrix3<S>::multiply(const Matrix3& mat)
{
*this = (*this)*mat;
}
//----------------------------------------------------------------------------------------------------
///
//----------------------------------------------------------------------------------------------------

View File

@ -44,12 +44,15 @@ public:
explicit Matrix4(const Matrix3<S>& other);
template<typename T>
explicit Matrix4(const T& other);
explicit Matrix4(const Matrix4<T>& other);
inline Matrix4& operator=(const Matrix4& rhs);
bool equals(const Matrix4& mat) const;
bool operator==(const Matrix4& rhs) const;
bool operator!=(const Matrix4& rhs) const;
void multiply(const Matrix4& mat);
const Matrix4 operator*(const Matrix4& rhs) const;
const Vector4<S> operator*(const Vector4<S>& rhs) const;
@ -58,10 +61,10 @@ public:
void setZero();
bool isZero() const;
inline S& operator()(int row, int col);
inline S operator()(int row, int col) const;
inline void setRowCol(int row, int col, S value);
inline S rowCol(int row, int col) const;
inline S& operator()(int row, int col);
inline S operator()(int row, int col) const;
void setRow(int row, const Vector4<S>& vector);
Vector4<S> row(int row) const;
@ -89,6 +92,7 @@ public:
inline const S* ptr() const;
static Matrix4 fromTranslation(const Vector3<S>& trans);
static Matrix4 fromScaling(const Vector3<S>& scale);
static Matrix4 fromRotation(Vector3<S> axis, S angle);
static Matrix4 fromCoordSystemAxes(const Vector3<S>* xAxis, const Vector3<S>* yAxis, const Vector3<S>* zAxis);
@ -107,6 +111,7 @@ private:
S m_v[16];
};
template<typename S>
Vector4<S> operator*(const Matrix4<S>& m, const Vector4<S>& v);

View File

@ -131,7 +131,7 @@ Matrix4<S>::Matrix4(const Matrix3<S>& other)
//----------------------------------------------------------------------------------------------------
template<typename S>
template<typename T>
Matrix4<S>::Matrix4(const T& other)
Matrix4<S>::Matrix4(const Matrix4<T>& other)
{
m_v[e00] = static_cast<S>(other.rowCol(0, 0));
m_v[e10] = static_cast<S>(other.rowCol(1, 0));
@ -163,19 +163,29 @@ inline Matrix4<S>& Matrix4<S>::operator=(const Matrix4& obj)
}
//----------------------------------------------------------------------------------------------------
/// Check if matrices are equal using exact comparisons.
//----------------------------------------------------------------------------------------------------
template<typename S>
bool Matrix4<S>::equals(const Matrix4& mat) const
{
for (int i = 0; i < 16; i++)
{
if (m_v[i] != mat.m_v[i]) return false;
}
return true;
}
//----------------------------------------------------------------------------------------------------
/// Comparison operator. Checks for equality using exact comparisons.
//----------------------------------------------------------------------------------------------------
template <typename S>
bool Matrix4<S>::operator==(const Matrix4& rhs) const
{
int i;
for (i = 0; i < 16; i++)
{
if (m_v[i] != rhs.m_v[i]) return false;
}
return true;
return this->equals(rhs);
}
@ -195,6 +205,16 @@ bool Matrix4<S>::operator!=(const Matrix4& rhs) const
}
//--------------------------------------------------------------------------------------------------
/// Multiplies this matrix M with the matrix \a mat, M = M*mat
//--------------------------------------------------------------------------------------------------
template<typename S>
void Matrix4<S>::multiply(const Matrix4& mat)
{
*this = (*this)*mat;
}
//----------------------------------------------------------------------------------------------------
///
//----------------------------------------------------------------------------------------------------
@ -497,9 +517,9 @@ void Matrix4<S>::setTranslation(const Vector3<S>& trans)
//----------------------------------------------------------------------------------------------------
/// Adds translation by pre-multiplying the matrix with a matrix containing the specified translation
///
/// Adds translation to this (transformation) matrix by pre multiplying the current matrix M with
/// a matrix containing the specified translation. Calling this function has the effect of doing the
/// multiplication T x M where T is a matrix that only contains translation.
/// Adds translation to this (transformation) matrix by pre-multiplying the current matrix M with
/// a matrix T containing only the specified translation.
/// Calling this function has the effect of doing the multiplication M' = T x M
///
/// \param trans Specifies the X, Y and Z components of the translation.
//----------------------------------------------------------------------------------------------------
@ -526,9 +546,9 @@ void Matrix4<S>::translatePreMultiply(const Vector3<S>& trans)
//----------------------------------------------------------------------------------------------------
/// Adds translation by post-multiplying the matrix with a matrix containing the specified translation
///
/// Adds translation to this (transformation) matrix by post multiplying the current matrix M with
/// a matrix containing the specified translation. Calling this function has the effect of doing the
/// multiplication M x T where T is a matrix that only contains translation.
/// Adds translation to this (transformation) matrix by post-multiplying the current matrix M with
/// a matrix T containing only the specified translation.
/// Calling this function has the effect of doing the multiplication M' = M x T
///
/// \param trans Specifies the X, Y and Z coordinates of the translation.
//----------------------------------------------------------------------------------------------------
@ -770,6 +790,19 @@ Matrix4<S> Matrix4<S>::fromTranslation(const Vector3<S>& trans)
}
//----------------------------------------------------------------------------------------------------
/// Static member function that creates a transformation matrix containing only scaling
//----------------------------------------------------------------------------------------------------
template <typename S>
Matrix4<S> Matrix4<S>::fromScaling(const Vector3<S>& scale)
{
return Matrix4(scale.x(), 0, 0, 0,
0, scale.y(), 0, 0,
0, 0, scale.z(), 0,
0, 0, 0, 1);
}
//----------------------------------------------------------------------------------------------------
///
//----------------------------------------------------------------------------------------------------

View File

@ -32,7 +32,7 @@ namespace cvf {
///
/// Class defining a plane in space
///
/// The class describes a plane by the equation: \f$Ax + By + Cz + Dx = 0\f$
/// The class describes a plane by the equation: \f$Ax + By + Cz + D = 0\f$
/// The plane's normal is defined by the coefficients \f$[A, B, C]\f$
///
//==================================================================================================
@ -425,6 +425,114 @@ bool Plane::intersect(const Plane& other, Vec3d* point, Vec3d* direction) const
return true;
}
//--------------------------------------------------------------------------------------------------
/// Find intersection between a line segment and a plane
///
/// \param a Start of line segment
/// \param b End of line segment
/// \param intersection Returns intersection point if not NULL
///
/// \return True if line segment intersects the plane
//--------------------------------------------------------------------------------------------------
bool Plane::intersect(const Vec3d& a, const Vec3d& b, Vec3d* intersection) const
{
// From Real-Time Collision Detection by Christer Eriscon, published by Morgen Kaufmann Publishers, (c) 2005 Elsevier Inc
// Compute the t value for the directed line ab intersecting the plane
Vec3d ab = b - a;
double t = (-m_D - (normal() * a)) / (normal() * ab);
// If t in [0..1] compute and return intersection point
if (t >= 0.0 && t <= 1.0)
{
if (intersection)
{
*intersection = a + t * ab;
}
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
/// Classify where the point is located relative to the plane
///
/// \return Plane::FRONT if the point is located on the side the plane normal is pointing\n
/// Plane::BACK if the point is located on the opposite side the plane normal is pointing\n
/// Plane::ON if the point is located in the plane
///
//--------------------------------------------------------------------------------------------------
Plane::Side Plane::side(const Vec3d& point) const
{
double d = distanceSquared(point);
if (d > 0.0)
{
return FRONT;
}
else if (d < 0.0)
{
return BACK;
}
else
{
return ON;
}
}
//--------------------------------------------------------------------------------------------------
/// Classify where the points are located relative to the plane
///
/// \param points Points to test for location relative the plane
///
/// \return Plane::FRONT if points are either Plane::FRONT or Plane::ON\n
/// Plane::BACK if points are either Plane::BACK or Plane::ON\n
/// Plane::ON if all points are Plane::ON\n
/// Plane::BOTH if points are located on both sides
//--------------------------------------------------------------------------------------------------
Plane::Side Plane::side(const Vec3dArray& points) const
{
// Code taken from
// http://code.google.com/p/papervision3d/source/browse/trunk/as3/trunk/src/org/papervision3d/core/math/util/ClassificationUtil.as
cvf::uint frontCount = 0;
cvf::uint backCount = 0;
for (size_t i = 0; i < points.size(); i++)
{
Side s = side(points[i]);
if (s == FRONT)
{
frontCount++;
}
else if (s == BACK)
{
backCount++;
}
}
if (frontCount > 0 && backCount == 0)
{
return FRONT;
}
else if (frontCount == 0 && backCount > 0)
{
return BACK;
}
else if (frontCount > 0 && backCount > 0)
{
return BOTH;
}
else
{
return ON;
}
}
} // namespace cvf

View File

@ -22,6 +22,7 @@
#include "cvfObject.h"
#include "cvfVector3.h"
#include "cvfMatrix4.h"
#include "cvfArray.h"
namespace cvf {
@ -33,6 +34,9 @@ namespace cvf {
//=================================================================================================
class Plane : public Object
{
public:
enum Side { FRONT, BACK, ON, BOTH };
public:
Plane();
Plane(double A, double B, double C, double D);
@ -68,6 +72,10 @@ public:
Vec3d projectPoint(const Vec3d& point) const;
bool intersect(const Plane& other, Vec3d* point, Vec3d* direction = NULL) const;
bool intersect(const Vec3d& a, const Vec3d& b, Vec3d* intersection) const;
Side side(const Vec3d& point) const;
Side side(const Vec3dArray& points) const;
private:
double m_A; // Plane equation coefficients

View File

@ -202,7 +202,8 @@ void Quat<S>::toAxisAngle(Vector3<S>* rotationAxis, S* angle) const
Quat nQ(*this);
nQ.normalize();
S cos_a = nQ.m_w;
// Clamp to acos' input domain
S cos_a = Math::clamp(nQ.m_w, static_cast<S>(-1), static_cast<S>(1));
*angle = 2*Math::acos(cos_a);
S sin_a = Math::sqrt(1 - cos_a*cos_a);

View File

@ -50,6 +50,7 @@ public:
void setHeight(T height);
bool isValid() const;
void normalize();
void include(const Vector2<T>& coord);
void include(const Rect& rect);
@ -57,8 +58,6 @@ public:
bool contains(const Vector2<T>& coord) const;
bool intersects(const Rect& rect) const;
void normalize();
void translate(const Vector2<T>& offset);
bool segmentIntersect(const Vec2d& p1, const Vec2d& p2, Vec2d* intersect1, Vec2d* intersect2);

View File

@ -28,6 +28,7 @@ namespace cvf {
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -48,7 +49,6 @@ template <typename T>
Rect<T>::Rect(T minX, T minY, T width, T height)
{
m_minPos.set(minX, minY);
m_width = width;
m_height = height;
}
@ -186,7 +186,30 @@ void Rect<T>::setHeight(T height)
template <typename T>
bool Rect<T>::isValid() const
{
return m_width > 0.0 && m_height > 0.0;
return (m_width > 0.0) && (m_height > 0.0);
}
//--------------------------------------------------------------------------------------------------
/// Normalizes the rectangle
///
/// Ensures that the rectangle has a non-negative width and height. If width or height is negative,
/// the corresponding min component will be moved.
//--------------------------------------------------------------------------------------------------
template <typename T>
void Rect<T>::normalize()
{
if (m_width < 0.0)
{
m_width = -m_width;
m_minPos.x() -= m_width;
}
if (m_height < 0.0)
{
m_height = -m_height;
m_minPos.y() -= m_height;
}
}
@ -240,12 +263,16 @@ void Rect<T>::include(const Rect& rect)
T left = m_minPos.x();
T right = m_minPos.x();
if (m_width < 0)
if (m_width < 0.0)
{
left += m_width;
}
else
{
right += m_width;
}
if (rect.width() < 0)
if (rect.width() < 0.0)
{
left = CVF_MIN(left, rect.min().x() + rect.width());
right = CVF_MAX(right, rect.min().x());
@ -258,7 +285,7 @@ void Rect<T>::include(const Rect& rect)
T bottom = m_minPos.y();
T top = m_minPos.y();
if (m_height < 0)
if (m_height < 0.0)
{
bottom += m_height;
}
@ -267,7 +294,7 @@ void Rect<T>::include(const Rect& rect)
top += m_height;
}
if (rect.height() < 0)
if (rect.height() < 0.0)
{
bottom = CVF_MIN(bottom, rect.min().y() + rect.height());
top = CVF_MAX(top, rect.min().y());
@ -285,14 +312,16 @@ void Rect<T>::include(const Rect& rect)
//--------------------------------------------------------------------------------------------------
/// Check if the rectangle contains the specified coordinate
///
/// Returns true if the point is inside or on the edge of the rectangle; otherwise returns false.
//--------------------------------------------------------------------------------------------------
template <typename T>
bool Rect<T>::contains(const Vector2<T>& coord) const
{
T left = m_minPos.x();
T right = m_minPos.x();
if (m_width < 0)
if (m_width < 0.0)
{
left += m_width;
}
@ -314,7 +343,7 @@ bool Rect<T>::contains(const Vector2<T>& coord) const
T bot = m_minPos.y();
T top = m_minPos.y();
if (m_height < 0)
if (m_height < 0.0)
{
bot += m_height;
}
@ -346,7 +375,7 @@ bool Rect<T>::intersects(const Rect& rect) const
{
T left1 = m_minPos.x();
T right1 = m_minPos.x();
if (m_width < 0)
if (m_width < 0.0)
{
left1 += m_width;
}
@ -363,7 +392,7 @@ bool Rect<T>::intersects(const Rect& rect) const
T left2 = rect.min().x();
T right2 = rect.min().x();
if (rect.width() < 0)
if (rect.width() < 0.0)
{
left2 += rect.width();
}
@ -385,7 +414,7 @@ bool Rect<T>::intersects(const Rect& rect) const
T bot1 = m_minPos.y();
T top1 = m_minPos.y();
if (m_height < 0)
if (m_height < 0.0)
{
bot1 += m_height;
}
@ -402,7 +431,7 @@ bool Rect<T>::intersects(const Rect& rect) const
T bot2 = rect.min().y();
T top2 = rect.min().y();
if (rect.height() < 0)
if (rect.height() < 0.0)
{
bot2 += rect.height();
}
@ -426,26 +455,6 @@ bool Rect<T>::intersects(const Rect& rect) const
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
template <typename T>
void Rect<T>::normalize()
{
if (m_width < 0)
{
m_width = -m_width;
m_minPos.x() -= m_width;
}
if (m_height < 0)
{
m_height = -m_height;
m_minPos.y() -= m_height;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -462,8 +471,11 @@ void Rect<T>::translate(const Vector2<T>& offset)
template <typename T>
Rect<T> Rect<T>::fromMinMax(const Vector2<T>& min, const Vector2<T>& max)
{
Rect<T> rect(min, max.x() - min.x(), max.y() - min.y());
// Enforce min/max - otherwise we'll get bogus results for unsigned types
CVF_ASSERT(min.x() <= max.x());
CVF_ASSERT(min.y() <= max.y());
Rect<T> rect(min, max.x() - min.x(), max.y() - min.y());
return rect;
}
@ -519,7 +531,6 @@ bool Rect<T>::segmentIntersect(const Vec2d& p1, const Vec2d& p2, Vec2d* intersec
return false;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -43,44 +43,45 @@ public:
explicit Vector2(const T& other);
inline Vector2& operator=(const Vector2& rhs);
inline bool equals(const Vector2& other) const;
inline bool operator==(const Vector2& rhs) const;
inline bool operator!=(const Vector2& rhs) const;
inline void add(const Vector2& other);
inline void subtract(const Vector2& other);
inline const Vector2 operator+(const Vector2& rhs) const;
inline const Vector2 operator-(const Vector2& rhs) const;
inline const Vector2 operator*(S scalar) const;
inline const Vector2 operator/(S scalar) const;
template<typename T>
friend inline const Vector2<T> operator*(T scalar, const Vector2<T>& rhs);
inline const Vector2 operator-() const;
inline Vector2& operator+=(const Vector2& rhs);
inline Vector2& operator-=(const Vector2& rhs);
inline const Vector2 operator-() const;
inline void scale(S scalar);
inline const Vector2 operator*(S scalar) const;
inline const Vector2 operator/(S scalar) const;
inline Vector2& operator*=(S scalar);
inline Vector2& operator/=(S scalar);
inline S dot(const Vector2& other) const;
inline S operator*(const Vector2& rhs) const; // Dot product
template<typename T>
void set(const T& other);
inline void set(S x, S y);
inline void setZero();
inline const S& x() const { return m_v[0]; } ///< Get the X element of the vector
inline const S& y() const { return m_v[1]; } ///< Get the Y element of the vector
inline S& x() { return m_v[0]; } ///< Get a reference to the X element of the vector. E.g. x() = 1;
inline S& y() { return m_v[1]; } ///< Get a reference to the Y element of the vector. E.g. y() = 2;
inline const S& operator[](int index) const; // Get component 0 or 1. E.g. x = v[0];
inline S& operator[](int index); // Set component 0 or 1. E.g. v[0] = x;
inline S operator*(const Vector2& rhs) const; // Dot product
inline S* ptr() { return m_v; } ///< Get a raw pointer to the internal c array of type S.
inline const S* ptr() const { return m_v; } ///< Get a const raw pointer to the internal c array of type S.
inline const S& x() const { return m_v[0]; } ///< Get the X element of the vector
inline const S& y() const { return m_v[1]; } ///< Get the Y element of the vector
inline S& x() { return m_v[0]; } ///< Get a reference to the X element of the vector. E.g. x() = 1;
inline S& y() { return m_v[1]; } ///< Get a reference to the Y element of the vector. E.g. y() = 2;
inline S* ptr() { return m_v; } ///< Get a raw pointer to the internal c array of type S.
inline const S* ptr() const { return m_v; } ///< Get a const raw pointer to the internal c array of type S.
inline void set(S x, S y);
inline void setZero();
inline bool isZero() const;
inline bool isUndefined() const;
template<typename T>
void set(const T& other);
inline bool isZero() const;
inline bool isUndefined() const;
bool normalize();
const Vector2 getNormalized(bool* normalizationOK = NULL) const;
@ -95,10 +96,15 @@ public:
static const Vector2 ZERO; ///< Null vector <0, 0>
static const Vector2 UNDEFINED; ///< Undefined vector
private:
template<typename T>
friend inline const Vector2<T> operator*(T scalar, const Vector2<T>& rhs);
private:
S m_v[2];
};
typedef Vector2<float> Vec2f; ///< A vector with float components
typedef Vector2<double> Vec2d; ///< A vector with double components
typedef Vector2<int> Vec2i; ///< A vector with int components

View File

@ -85,6 +85,16 @@ Vector2<S>& Vector2<S>::operator=(const Vector2& other)
}
//--------------------------------------------------------------------------------------------------
/// Check if two vectors are equal. An exact match is required.
//--------------------------------------------------------------------------------------------------
template<typename S>
bool Vector2<S>::equals(const Vector2& other) const
{
return (*this == other);
}
//--------------------------------------------------------------------------------------------------
/// Check if two vectors are equal. An exact match is required.
//--------------------------------------------------------------------------------------------------
@ -115,6 +125,26 @@ inline const Vector2<S> Vector2<S>::operator+(const Vector2& rhs) const
}
//--------------------------------------------------------------------------------------------------
/// Adds the vector \a other to this vector
//--------------------------------------------------------------------------------------------------
template<typename S>
void Vector2<S>::add(const Vector2& other)
{
(*this) += other;
}
//--------------------------------------------------------------------------------------------------
/// Subtracts the vector \a other from this vector
//--------------------------------------------------------------------------------------------------
template<typename S>
void cvf::Vector2<S>::subtract(const Vector2& other)
{
(*this) -= other;
}
//--------------------------------------------------------------------------------------------------
/// Compute this-rhs and return the result.
//--------------------------------------------------------------------------------------------------
@ -125,6 +155,16 @@ inline const Vector2<S> Vector2<S>::operator-(const Vector2& rhs) const
}
//--------------------------------------------------------------------------------------------------
/// Scale this vector by the given scalar
//--------------------------------------------------------------------------------------------------
template<typename S>
void Vector2<S>::scale(S scalar)
{
(*this) *= scalar;
}
//--------------------------------------------------------------------------------------------------
/// Return this vector scaled by the given scalar
//--------------------------------------------------------------------------------------------------
@ -240,6 +280,16 @@ inline S& Vector2<S>::operator[](int index)
}
//--------------------------------------------------------------------------------------------------
/// Compute the dot product of this and \a other
//--------------------------------------------------------------------------------------------------
template<typename S>
S Vector2<S>::dot(const Vector2& other) const
{
return (*this)*other;
}
//--------------------------------------------------------------------------------------------------
/// Compute the dot product of this and rhs and return the result (scalar)
///

View File

@ -52,47 +52,49 @@ public:
explicit Vector3(const T& other);
inline Vector3& operator=(const Vector3& rhs);
inline bool equals(const Vector3& other) const;
inline bool operator==(const Vector3& rhs) const;
inline bool operator!=(const Vector3& rhs) const;
inline void add(const Vector3& other);
inline void subtract(const Vector3& other);
inline const Vector3 operator+(const Vector3& rhs) const;
inline const Vector3 operator-(const Vector3& rhs) const;
inline const Vector3 operator*(S scalar) const;
inline const Vector3 operator/(S scalar) const;
template<typename T>
friend inline const Vector3<T> operator*(T scalar, const Vector3<T>& rhs);
inline const Vector3 operator-() const;
inline Vector3& operator+=(const Vector3& rhs);
inline Vector3& operator-=(const Vector3& rhs);
inline const Vector3 operator-() const;
inline void scale(S scalar);
inline const Vector3 operator*(S scalar) const;
inline const Vector3 operator/(S scalar) const;
inline Vector3& operator*=(S scalar);
inline Vector3& operator/=(S scalar);
inline S dot(const Vector3& other) const;
inline S operator*(const Vector3& rhs) const; // Dot product
inline void cross(const Vector3& v1, const Vector3& v2);
inline const Vector3 operator^(const Vector3& rhs) const; // Cross product
template<typename T>
void set(const T& other);
inline void set(S x, S y, S z);
inline void setZero();
inline const S& x() const { return m_v[0]; } ///< Get the X element of the vector
inline const S& y() const { return m_v[1]; } ///< Get the Y element of the vector
inline const S& z() const { return m_v[2]; } ///< Get the Z element of the vector
inline S& x() { return m_v[0]; } ///< Get a reference to the X element of the vector. E.g. x() = 1;
inline S& y() { return m_v[1]; } ///< Get a reference to the Y element of the vector. E.g. y() = 2;
inline S& z() { return m_v[2]; } ///< Get a reference to the Z element of the vector. E.g. z() = 3;
inline const S& operator[](int index) const; // Get component 0,1,2. E.g. x = v[0];
inline S& operator[](int index); // Set component 0,1,2. E.g. v[0] = x;
inline S operator*(const Vector3& rhs) const; // Dot product
inline const Vector3 operator^(const Vector3& rhs) const; // Cross product
inline S* ptr() { return m_v; } ///< Get a raw pointer to the internal c array of type S.
inline const S* ptr() const { return m_v; } ///< Get a const raw pointer to the internal c array of type S.
inline const S& x() const { return m_v[0]; } ///< Get the X element of the vector
inline const S& y() const { return m_v[1]; } ///< Get the Y element of the vector
inline const S& z() const { return m_v[2]; } ///< Get the Z element of the vector
inline S& x() { return m_v[0]; } ///< Get a reference to the X element of the vector. E.g. x() = 1;
inline S& y() { return m_v[1]; } ///< Get a reference to the Y element of the vector. E.g. y() = 2;
inline S& z() { return m_v[2]; } ///< Get a reference to the Z element of the vector. E.g. z() = 3;
inline S* ptr() { return m_v; } ///< Get a raw pointer to the internal c array of type S.
inline const S* ptr() const { return m_v; } ///< Get a const raw pointer to the internal c array of type S.
inline void set(S x, S y, S z);
inline void setZero();
inline bool isZero() const;
inline bool isUndefined() const;
template<typename T>
void set(const T& other);
inline bool isZero() const;
inline bool isUndefined() const;
bool normalize();
const Vector3 getNormalized(bool* normalizationOK = NULL) const;
@ -122,10 +124,15 @@ public:
static const Vector3 ZERO; ///< Null vector <0, 0, 0>
static const Vector3 UNDEFINED; ///< Undefined vector
private:
template<typename T>
friend inline const Vector3<T> operator*(T scalar, const Vector3<T>& rhs);
private:
S m_v[3];
};
typedef Vector3<float> Vec3f; ///< A vector with float components
typedef Vector3<double> Vec3d; ///< A vector with double components
typedef Vector3<int> Vec3i; ///< A vector with int components

View File

@ -115,6 +115,17 @@ Vector3<S>& Vector3<S>::operator=(const Vector3& other)
}
//--------------------------------------------------------------------------------------------------
/// Check if two vectors are equal. An exact match is required.
//--------------------------------------------------------------------------------------------------
template<typename S>
bool Vector3<S>::equals(const Vector3& other) const
{
return (*this == other);
}
//--------------------------------------------------------------------------------------------------
/// Check if two vectors are equal. An exact match is required.
//--------------------------------------------------------------------------------------------------
@ -135,6 +146,26 @@ inline bool Vector3<S>::operator!=(const Vector3& rhs) const
}
//--------------------------------------------------------------------------------------------------
/// Adds the vector \a other to this vector
//--------------------------------------------------------------------------------------------------
template<typename S>
void cvf::Vector3<S>::add(const Vector3& other)
{
(*this) += other;
}
//--------------------------------------------------------------------------------------------------
/// Subtracts the vector \a other from this vector
//--------------------------------------------------------------------------------------------------
template<typename S>
void cvf::Vector3<S>::subtract(const Vector3& other)
{
(*this) -= other;
}
//--------------------------------------------------------------------------------------------------
/// Returns the sum of this vector and the rhs vector
//--------------------------------------------------------------------------------------------------
@ -155,6 +186,16 @@ inline const Vector3<S> Vector3<S>::operator-(const Vector3& rhs) const
}
//--------------------------------------------------------------------------------------------------
/// Scale this vector by the given scalar
//--------------------------------------------------------------------------------------------------
template<typename S>
void Vector3<S>::scale(S scalar)
{
(*this) *= scalar;
}
//--------------------------------------------------------------------------------------------------
/// Return this vector scaled by the given scalar
//--------------------------------------------------------------------------------------------------
@ -274,6 +315,16 @@ inline S& Vector3<S>::operator[](int index)
}
//--------------------------------------------------------------------------------------------------
/// Compute the dot product of this and \a other
//--------------------------------------------------------------------------------------------------
template<typename S>
S Vector3<S>::dot(const Vector3& other) const
{
return (*this)*other;
}
//--------------------------------------------------------------------------------------------------
/// Compute the dot product of this and rhs and return the result (scalar)
///
@ -289,6 +340,17 @@ inline S Vector3<S>::operator*(const Vector3& rhs) const
}
//--------------------------------------------------------------------------------------------------
/// Sets this vector to the cross product of vectors \a v1 and \a v2
//--------------------------------------------------------------------------------------------------
template<typename S>
void cvf::Vector3<S>::cross(const Vector3& v1, const Vector3& v2)
{
*this = v1 ^ v2;
}
//--------------------------------------------------------------------------------------------------
/// Compute the cross product of this and rhs and return the result (vector)
///

View File

@ -43,50 +43,55 @@ public:
explicit Vector4(const T& other);
inline Vector4& operator=(const Vector4& rhs);
inline bool equals(const Vector4& other) const;
inline bool operator==(const Vector4& rhs) const;
inline bool operator!=(const Vector4& rhs) const;
inline void add(const Vector4& other);
inline void subtract(const Vector4& other);
inline const Vector4 operator+(const Vector4& rhs) const;
inline const Vector4 operator-(const Vector4& rhs) const;
inline const Vector4 operator*(S scalar) const;
inline const Vector4 operator/(S scalar) const;
inline const Vector4 operator-() const;
inline Vector4& operator+=(const Vector4& rhs);
inline Vector4& operator-=(const Vector4& rhs);
inline const Vector4 operator-() const;
inline void scale(S scalar);
inline const Vector4 operator*(S scalar) const;
inline const Vector4 operator/(S scalar) const;
inline Vector4& operator*=(S scalar);
inline Vector4& operator/=(S scalar);
inline S dot(const Vector4& other) const;
inline S operator*(const Vector4& rhs) const; // Dot product
template<typename T>
void set(const T& other);
inline void set(S x, S y, S z, S w);
inline void setZero();
inline const S& x() const { return m_v[0]; } ///< Get the X element of the vector
inline const S& y() const { return m_v[1]; } ///< Get the Y element of the vector
inline const S& z() const { return m_v[2]; } ///< Get the Z element of the vector
inline const S& w() const { return m_v[3]; } ///< Get the W element of the vector
inline S& x() { return m_v[0]; } ///< Get a reference to the X element of the vector. E.g. x() = 1;
inline S& y() { return m_v[1]; } ///< Get a reference to the Y element of the vector. E.g. y() = 2;
inline S& z() { return m_v[2]; } ///< Get a reference to the Z element of the vector. E.g. z() = 3;
inline S& w() { return m_v[3]; } ///< Get a reference to the W element of the vector. E.g. w() = 3;
inline const S& operator[](int index) const; // Get component 0,1,2,3. E.g. x = v[0];
inline S& operator[](int index); // Set component 0,1,2,3. E.g. v[0] = x;
inline S operator*(const Vector4& rhs) const; // Dot product
inline S* ptr() { return m_v; } ///< Get a raw pointer to the internal c array of type S.
inline const S* ptr() const { return m_v; } ///< Get a const raw pointer to the internal c array of type S.
inline const S& x() const { return m_v[0]; } ///< Get the X element of the vector
inline const S& y() const { return m_v[1]; } ///< Get the Y element of the vector
inline const S& z() const { return m_v[2]; } ///< Get the Z element of the vector
inline const S& w() const { return m_v[3]; } ///< Get the W element of the vector
inline S& x() { return m_v[0]; } ///< Get a reference to the X element of the vector. E.g. x() = 1;
inline S& y() { return m_v[1]; } ///< Get a reference to the Y element of the vector. E.g. y() = 2;
inline S& z() { return m_v[2]; } ///< Get a reference to the Z element of the vector. E.g. z() = 3;
inline S& w() { return m_v[3]; } ///< Get a reference to the W element of the vector. E.g. w() = 3;
inline bool isZero() const;
inline S* ptr() { return m_v; } ///< Get a raw pointer to the internal c array of type S.
inline const S* ptr() const { return m_v; } ///< Get a const raw pointer to the internal c array of type S.
bool normalize();
const Vector4 getNormalized(bool* normalizationOK = NULL) const;
inline void set(S x, S y, S z, S w);
inline void setZero();
inline bool isZero() const;
template<typename T>
void set(const T& other);
bool normalize();
Vector4 normalized(bool* normalizationOK = NULL) const;
inline S length() const;
inline S lengthSquared() const;
bool setLength(S newLength);
inline S length() const;
inline S lengthSquared() const;
bool setLength(S newLength);
public:
static const Vector4 ZERO; ///< Null vector <0, 0, 0>
@ -96,6 +101,7 @@ private:
S m_v[4];
};
typedef Vector4<float> Vec4f; ///< A vector with float components
typedef Vector4<double> Vec4d; ///< A vector with double components
typedef Vector4<int> Vec4i; ///< A vector with int components

View File

@ -102,6 +102,17 @@ Vector4<S>::Vector4(const Vector3<S>& other, S w)
}
//--------------------------------------------------------------------------------------------------
/// Check if two vectors are equal. An exact match is required.
//--------------------------------------------------------------------------------------------------
template<typename S>
bool Vector4<S>::equals(const Vector4& other) const
{
return (*this == other);
}
//--------------------------------------------------------------------------------------------------
/// Check if two vectors are equal. An exact match is required.
//--------------------------------------------------------------------------------------------------
@ -122,6 +133,26 @@ inline bool Vector4<S>::operator!=(const Vector4& rhs) const
}
//--------------------------------------------------------------------------------------------------
/// Adds the vector \a other to this vector
//--------------------------------------------------------------------------------------------------
template<typename S>
void cvf::Vector4<S>::add(const Vector4& other)
{
(*this) += other;
}
//--------------------------------------------------------------------------------------------------
/// Subtracts the vector \a other from this vector
//--------------------------------------------------------------------------------------------------
template<typename S>
void cvf::Vector4<S>::subtract(const Vector4& other)
{
(*this) -= other;
}
//--------------------------------------------------------------------------------------------------
/// Returns the sum of this vector and the rhs vector
//--------------------------------------------------------------------------------------------------
@ -142,6 +173,17 @@ inline const Vector4<S> Vector4<S>::operator-(const Vector4& rhs) const
}
//--------------------------------------------------------------------------------------------------
/// Scale this vector by the given scalar
//--------------------------------------------------------------------------------------------------
template<typename S>
void Vector4<S>::scale(S scalar)
{
(*this) *= scalar;
}
//--------------------------------------------------------------------------------------------------
/// Return this vector scaled by the given scalar
//--------------------------------------------------------------------------------------------------
@ -258,6 +300,16 @@ inline S& Vector4<S>::operator[](int index)
}
//--------------------------------------------------------------------------------------------------
/// Compute the dot product of this and \a other
//--------------------------------------------------------------------------------------------------
template<typename S>
S Vector4<S>::dot(const Vector4& other) const
{
return (*this)*other;
}
//--------------------------------------------------------------------------------------------------
/// Compute the dot product of this and rhs and return the result (scalar)
///
@ -384,7 +436,7 @@ bool Vector4<S>::normalize()
/// Returns a normalized version of the current vector. The vector is unchanged.
//--------------------------------------------------------------------------------------------------
template<typename S>
Vector4<S> Vector4<S>::normalized(bool* normalizationOK) const
const Vector4<S> Vector4<S>::getNormalized(bool* normalizationOK) const
{
S len = length();
if (len > 0.0)

View File

@ -22,6 +22,6 @@
#define CVF_MAJOR_VERSION "0" // Major version number
#define CVF_MINOR_VERSION "1" // Minor version number
#define CVF_MINOR_VERSION "9" // Minor version number
#define CVF_SPECIAL_BUILD "" // Special build description
#define CVF_BUILD_NUMBER "2" // Build number. Increase for each shipment
#define CVF_BUILD_NUMBER "4" // Build number. Increase for each shipment

View File

@ -27,8 +27,8 @@
#include "cvfArrowGenerator.h"
#include "cvfBoundingBox.h"
#include "cvfBoxGenerator.h"
#include "cvfFrustum.h"
#include "cvfEdgeKey.h"
#include "cvfFrustum.h"
#include "cvfGeometryBuilder.h"
#include "cvfGeometryBuilderFaceList.h"
#include "cvfGeometryBuilderTriangles.h"
@ -37,5 +37,8 @@
#include "cvfOutlineEdgeExtractor.h"
#include "cvfPatchGenerator.h"
#include "cvfRay.h"
#include "cvfTriangleMeshEdgeExtractor.h"
#include "cvfTriangleVertexSplitter.h"
#include "cvfVertexCompactor.h"
#include "cvfVertexWelder.h"

View File

@ -253,7 +253,10 @@ bool OutlineEdgeExtractor::isFaceAngleAboveThreshold(size_t faceIdx1, size_t fac
return true;
}
double angle = Math::acos(n1*n2);
// Guard acos against out-of-domain input
const double dotProduct = Math::clamp(static_cast<double>(n1*n2), -1.0, 1.0);
const double angle = Math::acos(dotProduct);
if (Math::abs(angle) > m_creaseAngle)
{
return true;

View File

@ -282,40 +282,28 @@ uint TriangleVertexSplitter::processVertex(uint origVertexIndex, const Vec3f& fa
}
}
//--------------------------------------------------------------------------------------------------
/// Return true if the angle between the two normals are below the current crease angle.
/// Return true if the angle between the two normals is below the current crease angle.
//--------------------------------------------------------------------------------------------------
bool TriangleVertexSplitter::isNormalDifferenceBelowThreshold(const Vec3f& n1, const Vec3f& n2)
{
// If either vector is 0, there is probably some trouble with the triangle
// Return false so that it will be split
if (n1.isZero() || n2.isZero())
{
return false;
}
double dotProduct = n1*n2;
// Guard acos against out-of-domain input
const double dotProduct = Math::clamp(static_cast<double>(n1*n2), -1.0, 1.0);
if (dotProduct <= -1.0)
{
dotProduct = -1.0;
}
else if (dotProduct >= 1.0)
{
dotProduct = 1.0;
}
double angle = Math::acos(dotProduct);
const double angle = Math::acos(dotProduct);
if (Math::abs(angle) < m_creaseAngle)
{
return true;
}
else if (Math::abs(angle) >= m_creaseAngle)
{
return false;
}
return false;
}

View File

@ -31,7 +31,6 @@ cvfFramebufferObject.h
cvfGeometryBuilderDrawableGeo.h
cvfGlyph.h
cvfHitDetail.h
cvfLegendScalarMapper.h
cvfLibRender.h
cvfMatrixState.h
cvfOglRc.h
@ -42,8 +41,11 @@ cvfOpenGLContextGroup.h
cvfOpenGLResourceManager.h
cvfOpenGLTypes.h
cvfOverlayAxisCross.h
cvfOverlayScalarMapperLegend.h
cvfOverlayColorLegend.h
cvfOverlayImage.h
cvfOverlayItem.h
cvfOverlayNavigationCube.h
cvfOverlayTextBox.h
cvfPrimitiveSet.h
cvfPrimitiveSetDirect.h
@ -53,11 +55,23 @@ cvfPrimitiveSetIndexedUShort.h
cvfPrimitiveSetIndexedUShortScoped.h
cvfRenderbufferObject.h
cvfRenderState.h
cvfRenderStateBlending.h
cvfRenderStateColorMask.h
cvfRenderStateCullFace.h
cvfRenderStateDepth.h
cvfRenderStateFrontFace.h
cvfRenderStateLine.h
cvfRenderStatePoint.h
cvfRenderStatePolygonMode.h
cvfRenderStatePolygonOffset.h
cvfRenderStateSet.h
cvfRenderStateStencil.h
cvfRenderStateTextureBindings.h
cvfRenderStateTracker.h
cvfRenderState_FF.h
cvfSampler.h
cvfScalarMapper.h
cvfScalarMapperRangeBased.h
cvfScalarMapperContinuousLog.h
cvfScalarMapperContinuousLinear.h
cvfScalarMapperDiscreteLinear.h
@ -95,7 +109,6 @@ cvfFontManager.cpp
cvfGeometryBuilderDrawableGeo.cpp
cvfGlyph.cpp
cvfHitDetail.cpp
#cvfLegendScalarMapper.cpp
cvfMatrixState.cpp
cvfOglRc.cpp
cvfOpenGLCapabilities.cpp
@ -104,7 +117,11 @@ cvfOpenGLContextGroup.cpp
cvfOpenGLResourceManager.cpp
cvfOpenGL.cpp
cvfOverlayAxisCross.cpp
cvfOverlayScalarMapperLegend.cpp
cvfOverlayColorLegend.cpp
cvfOverlayImage.cpp
cvfOverlayItem.cpp
cvfOverlayNavigationCube.cpp
cvfOverlayTextBox.cpp
cvfPrimitiveSet.cpp
cvfPrimitiveSetDirect.cpp
@ -114,10 +131,22 @@ cvfPrimitiveSetIndexedUIntScoped.cpp
cvfPrimitiveSetIndexedUShortScoped.cpp
cvfRenderbufferObject.cpp
cvfRenderState.cpp
cvfRenderState_FF.cpp
cvfRenderStateBlending.cpp
cvfRenderStateColorMask.cpp
cvfRenderStateCullFace.cpp
cvfRenderStateDepth.cpp
cvfRenderStateFrontFace.cpp
cvfRenderStateLine.cpp
cvfRenderStatePoint.cpp
cvfRenderStatePolygonMode.cpp
cvfRenderStatePolygonOffset.cpp
cvfRenderStateSet.cpp
cvfRenderStateStencil.cpp
cvfRenderStateTextureBindings.cpp
cvfRenderStateTracker.cpp
cvfRenderState_FF.cpp
cvfScalarMapper.cpp
cvfScalarMapperRangeBased.cpp
cvfScalarMapperContinuousLog.cpp
cvfScalarMapperContinuousLinear.cpp
cvfScalarMapperDiscreteLinear.cpp

View File

@ -268,23 +268,56 @@ void Camera::setProjectionAsPixelExact2D()
/// the view to. The relativeDistance parameter specifies the distance from the camera to the
/// center of the bounding box
//--------------------------------------------------------------------------------------------------
void Camera::fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double relativeDistance)
void Camera::fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double distanceScaleFactor)
{
double boxRadius = boundingBox.radius();
CVF_ASSERT(projection() == PERSPECTIVE);
// Determine needed distance from center of model to eye point
double fovY = m_fieldOfViewYDeg;
double fovX = m_fieldOfViewYDeg*aspectRatio();
// TODO! !!! !! !!
CVF_UNUSED(distanceScaleFactor);
// The return values are the complete angle in degrees, get half in radians
fovX = Math::toRadians(fovX/2);
fovY = Math::toRadians(fovY/2);
cvf::Vec3d corners[8];
boundingBox.cornerVertices(corners);
// Use the largest distance
double dist1 = (fovX != 0) ? boxRadius*relativeDistance/Math::sin(fovX) : -1;
double dist2 = (fovY != 0) ? boxRadius*relativeDistance/Math::sin(fovY) : -1;
cvf::Vec3d upNorm = up.getNormalized();
cvf::Vec3d right = dir^up;
right.normalize();
cvf::Vec3d boxEyeNorm = (-dir).getNormalized();
double dist = CVF_MAX(dist1, dist2);
cvf::Plane planeTop;
planeTop.setFromPointAndNormal(boundingBox.center(), up);
cvf::Plane planeSide;
planeSide.setFromPointAndNormal(boundingBox.center(), right);
// m_fieldOfViewYDeg is the complete angle in degrees, get half in radians
double fovY = Math::toRadians(m_fieldOfViewYDeg/2.0);
double fovX = Math::atan(Math::tan(fovY)*aspectRatio());
double dist = 0;
for (size_t i = 0; i < 8; ++i)
{
cvf::Vec3d centerToCorner = corners[i] - boundingBox.center();
// local horizontal plane
cvf::Vec3d centerToCornerTop = planeTop.projectPoint(centerToCorner);
double rightCoord = centerToCornerTop*right;
double distRight = Math::abs(rightCoord/Math::tan(fovX));
distRight += centerToCornerTop*boxEyeNorm;
// local vertical plane
cvf::Vec3d centerToCornerSide = planeSide.projectPoint(centerToCorner);
double upCoord = centerToCornerSide*upNorm;
double distUp = Math::abs(upCoord/Math::tan(fovY));
distUp += (centerToCornerSide*boxEyeNorm);
// Adjust for the distance scale factor
distRight /= distanceScaleFactor;
distUp /= distanceScaleFactor;
dist = CVF_MAX(dist, distRight);
dist = CVF_MAX(dist, distUp);
}
// Avoid distances of 0 when model has no extent
if (!(dist > 0))
@ -293,19 +326,68 @@ void Camera::fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec
}
// Use old view direction, but look towards model center
Vec3d eye = boundingBox.center()- dir*dist;
Vec3d eye = boundingBox.center()- dir.getNormalized()*dist;
// Will update cached values
setFromLookAt(eye, boundingBox.center(), up);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Camera::fitViewOrtho(const BoundingBox& boundingBox, double eyeDist, const Vec3d& dir, const Vec3d& up, double adjustmentFactor)
{
// Algorithm:
// Project all points into the viewing plan. Find the distance along the right and up vector.
// Set the height of the frustum to this distance.
cvf::Vec3d corners[8];
boundingBox.cornerVertices(corners);
cvf::BoundingBox projBox;
cvf::Plane viewPlane;
viewPlane.setFromPointAndNormal(boundingBox.center(), -dir);
cvf::Vec3d upNorm = up.getNormalized();
cvf::Vec3d right = up^dir;
right.normalize();
double rightMin = cvf::UNDEFINED_DOUBLE_THRESHOLD;
double rightMax = -cvf::UNDEFINED_DOUBLE_THRESHOLD;
double upMin = cvf::UNDEFINED_DOUBLE_THRESHOLD;
double upMax = -cvf::UNDEFINED_DOUBLE_THRESHOLD;
for (size_t i = 0; i < 8; ++i)
{
cvf::Vec3d cornerInPlane = viewPlane.projectPoint(corners[i]);
cvf::Vec3d cornerVec = cornerInPlane-boundingBox.center();
double rightCoord = cornerVec*right;
rightMin = CVF_MIN(rightMin, rightCoord);
rightMax = CVF_MAX(rightMax, rightCoord);
double upCood = cornerVec*upNorm;
upMin = CVF_MIN(upMin, upCood);
upMax = CVF_MAX(upMax, upCood);
}
double deltaRight = rightMax - rightMin;
double deltaUp = upMax - upMin;
double newHeight = CVF_MAX(deltaUp, deltaRight/aspectRatio())/adjustmentFactor;
setProjectionAsOrtho(newHeight, m_nearPlane, m_farPlane);
Vec3d eye = boundingBox.center()- eyeDist*dir.getNormalized();
setFromLookAt(eye, boundingBox.center(), up);
}
//--------------------------------------------------------------------------------------------------
/// Set the front and back clipping planes close to the given bounding box (perspective projection)
///
/// Note that this will setup a perspective projection with the new clipping planes.
//--------------------------------------------------------------------------------------------------
void Camera::setClipPlanesFromBoundingBoxPerspective(const BoundingBox& boundingBox, double minNearPlaneDistance)
void Camera::setClipPlanesFromBoundingBox(const BoundingBox& boundingBox, double minNearPlaneDistance)
{
CVF_ASSERT(minNearPlaneDistance > 0);
@ -321,7 +403,14 @@ void Camera::setClipPlanesFromBoundingBoxPerspective(const BoundingBox& bounding
if (nearPlane < minNearPlaneDistance) nearPlane = minNearPlaneDistance;
if (farPlane <= nearPlane) farPlane = nearPlane + 1.0;
setProjectionAsPerspective(m_fieldOfViewYDeg, nearPlane, farPlane);
if (projection() == PERSPECTIVE)
{
setProjectionAsPerspective(m_fieldOfViewYDeg, nearPlane, farPlane);
}
else
{
setProjectionAsOrtho(m_frontPlaneFrustumHeight, nearPlane, farPlane);
}
}
@ -469,6 +558,42 @@ ref<Ray> Camera::rayFromWinCoord(int winCoordX, int winCoordY) const
}
//--------------------------------------------------------------------------------------------------
/// Construct a plane from a line specified in window coordinates
///
/// The plane will be constructed so that the specified line lies in the plane, and the plane
/// normal will be pointing left when moving along the line from start to end.
/// The coordinates (winCoordStart & winCoordEnd) are assumed to be in the window coordinate system
/// where <0,0> is in the top left corner.
//--------------------------------------------------------------------------------------------------
ref<Plane> Camera::planeFromLineWinCoord(Vec2i winCoordStart, Vec2i winCoordEnd) const
{
// Unproject works in OpenGL coord system with (0,0) in lower left corner, so flip the y-coordinates
winCoordStart.y() = static_cast<int>(m_viewport->height()) - winCoordStart.y();
winCoordEnd.y() = static_cast<int>(m_viewport->height()) - winCoordEnd.y();
Vec3d s0(0, 0, 0);
Vec3d e0(0, 0, 0);
Vec3d e1(0, 0, 0);
bool unprojOk = true;
unprojOk &= unproject(Vec3d(winCoordStart.x(), winCoordStart.y(), 0), &s0);
unprojOk &= unproject(Vec3d(winCoordEnd.x(), winCoordEnd.y(), 0), &e0);
unprojOk &= unproject(Vec3d(winCoordEnd.x(), winCoordEnd.y(), 1), &e1);
if (!unprojOk)
{
return NULL;
}
ref<Plane> plane = new Plane;
if (!plane->setFromPoints(s0, e0, e1))
{
return NULL;
}
return plane;
}
//--------------------------------------------------------------------------------------------------
/// Computes the maximum pixel area that the projected bounding box will occupy with the current camera settings.
///
@ -684,7 +809,7 @@ void Camera::updateCachedValues()
// Update the cached frustum
m_cachedViewFrustum = computeViewFrustum();
// Update the front plane pixel size (height)
CVF_ASSERT(m_viewport.notNull());
uint vpWidth = m_viewport->width();
@ -709,7 +834,7 @@ void Camera::updateCachedValues()
//--------------------------------------------------------------------------------------------------
Frustum Camera::computeViewFrustum() const
{
// See also
// See:
// http://www2.ravensoft.com/users/ggribb/plane%20extraction.pdf
// http://zach.in.tu-clausthal.de/teaching/cg_literatur/lighthouse3d_view_frustum_culling/index.html

View File

@ -63,8 +63,10 @@ public:
void setProjectionAsUnitOrtho();
void setProjectionAsPixelExact2D();
void fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double relativeDistance = 1.0);
void setClipPlanesFromBoundingBoxPerspective(const BoundingBox& boundingBox, double minNearPlaneDistance = 0.01);
void fitView(const BoundingBox& boundingBox, const Vec3d& dir, const Vec3d& up, double coverageFactor = 0.9);
void fitViewOrtho(const BoundingBox& boundingBox, double eyeDist, const Vec3d& dir, const Vec3d& up, double coverageFactor = 0.9);
void setClipPlanesFromBoundingBox(const BoundingBox& boundingBox, double minNearPlaneDistance = 0.01);
const Mat4d& viewMatrix() const;
const Mat4d& invertedViewMatrix() const;
@ -84,6 +86,7 @@ public:
const Viewport* viewport() const;
ref<Ray> rayFromWinCoord(int winCoordX, int winCoordY) const;
ref<Plane> planeFromLineWinCoord(Vec2i winCoordStart, Vec2i winCoordEnd) const;
bool unproject(const Vec3d& coord, Vec3d* out) const;
bool project(const Vec3d& point, Vec3d* out) const;

View File

@ -30,10 +30,13 @@
#include "cvfGlyph.h"
#include "cvfCamera.h"
#include "cvfShaderProgram.h"
#include "cvfRenderState.h"
#include "cvfViewport.h"
#include "cvfGeometryUtils.h"
#include "cvfMatrixState.h"
#include "cvfRenderStatePoint.h"
#include "cvfRenderStateDepth.h"
#include "cvfRenderStatePolygonOffset.h"
#include "cvfRenderStateBlending.h"
#ifndef CVF_OPENGL_ES
#include "cvfRenderState_FF.h"
@ -273,7 +276,7 @@ void DrawableText::renderText(OpenGLContext* oglContext, ShaderProgram* shaderPr
nudgeShader->clearUniformApplyTracking();
nudgeShader->applyFixedUniforms(oglContext, matrixState);
Point point(Point::PROGRAM_SIZE);
RenderStatePoint point(RenderStatePoint::PROGRAM_SIZE);
point.applyOpenGL(oglContext);
}
else
@ -284,27 +287,27 @@ void DrawableText::renderText(OpenGLContext* oglContext, ShaderProgram* shaderPr
}
#ifndef CVF_OPENGL_ES
Material_FF mat;
RenderStateMaterial_FF mat;
mat.enableColorMaterial(true);
Lighting_FF noLight(false);
RenderStateLighting_FF noLight(false);
noLight.applyOpenGL(oglContext);
#endif
}
Depth visibleCheckDepthRS(true, Depth::LEQUAL, false);
RenderStateDepth visibleCheckDepthRS(true, RenderStateDepth::LEQUAL, false);
visibleCheckDepthRS.applyOpenGL(oglContext);
PolygonOffset po;
RenderStatePolygonOffset po;
po.enablePointMode(true);
po.setFactor(-3.0f);
po.setUnits(-3.0f);
po.applyOpenGL(oglContext);
Blending addBlend;
RenderStateBlending addBlend;
addBlend.enableBlending(true);
addBlend.setFunction(Blending::ONE, Blending::ONE);
addBlend.setEquation(Blending::FUNC_ADD);
addBlend.setFunction(RenderStateBlending::ONE, RenderStateBlending::ONE);
addBlend.setEquation(RenderStateBlending::FUNC_ADD);
addBlend.applyOpenGL(oglContext);
}
@ -327,19 +330,19 @@ void DrawableText::renderText(OpenGLContext* oglContext, ShaderProgram* shaderPr
if (m_checkPosVisible)
{
PolygonOffset resetPO;
RenderStatePolygonOffset resetPO;
resetPO.applyOpenGL(oglContext);
Blending resetBlend;
RenderStateBlending resetBlend;
resetBlend.applyOpenGL(oglContext);
#ifndef CVF_OPENGL_ES
if (!shaderProgram)
{
Material_FF mat;
RenderStateMaterial_FF mat;
mat.applyOpenGL(oglContext);
Lighting_FF light;
RenderStateLighting_FF light;
light.applyOpenGL(oglContext);
}
#endif

View File

@ -50,51 +50,108 @@ Font::~Font()
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float Font::lineSpacing()
{
ref<Glyph> glyph = getGlyph(L'A');
float spacing = cvf::Math::floor(static_cast<float>(glyph->height())*1.75f);
return spacing;
}
//--------------------------------------------------------------------------------------------------
/// Get the extent (width and height) of the given text with this font in pixels
//--------------------------------------------------------------------------------------------------
cvf::Vec2ui Font::textExtent(const String& text)
{
Vec2ui textBB(0,0);
std::vector<cvf::String> lines = text.split("\n");
int minHeight = std::numeric_limits<int>::max();
int maxHeight = std::numeric_limits<int>::min();
size_t numCharacters = text.size();
for (size_t j = 0; j < numCharacters; j++)
float maxLineWidth = 0;
uint textHeight = 0;
uint lineSpacing = static_cast<uint>(this->lineSpacing());
for (size_t lineIdx = 0; lineIdx < lines.size(); ++lineIdx)
{
wchar_t character = text[j];
ref<Glyph> glyph = getGlyph(character);
String line = lines[lineIdx];
size_t numCharacters = line.size();
float lineWidth = 0;
// Find bottom and top with regards to baseline (Y = 0)
int minY = static_cast<int>(glyph->horizontalBearingY()) - static_cast<int>(glyph->height());
int maxY = glyph->horizontalBearingY();
if (minHeight > minY) minHeight = minY;
if (maxHeight < maxY) maxHeight = maxY;
uint charWidth = 0;
if (j < (numCharacters - 1))
for (size_t j = 0; j < numCharacters; ++j)
{
charWidth = advance(character, text[j + 1]);
wchar_t character = line[j];
// Jump to the next character in the string, if any
if (j < (numCharacters - 1))
{
float advance = static_cast<float>(this->advance(character, text[j + 1]));
lineWidth += advance;
}
else
{
ref<Glyph> glyph = getGlyph(character);
lineWidth += static_cast<float>(glyph->width()) + static_cast<float>(glyph->horizontalBearingX());
}
}
maxLineWidth = CVF_MAX(lineWidth, maxLineWidth);
if (lineIdx == 0)
{
ref<Glyph> glyph = getGlyph(L'A');
textHeight += glyph->height();
}
else
{
charWidth = glyph->width() + glyph->horizontalBearingX();
textHeight += lineSpacing;
}
textBB.x() += charWidth;
}
if (maxHeight < minHeight)
{
return Vec2ui(0,0);
}
textBB.y() = static_cast<uint>(maxHeight - minHeight);
return textBB;
return Vec2ui(static_cast<uint>(maxLineWidth), textHeight);
}
// Vec2ui textBB(0,0);
//
// int minHeight = std::numeric_limits<int>::max();
// int maxHeight = std::numeric_limits<int>::min();
//
// size_t numCharacters = text.size();
// for (size_t j = 0; j < numCharacters; j++)
// {
// wchar_t character = text[j];
// ref<Glyph> glyph = getGlyph(character);
//
// // Find bottom and top with regards to baseline (Y = 0)
// int minY = static_cast<int>(glyph->horizontalBearingY()) - static_cast<int>(glyph->height());
// int maxY = glyph->horizontalBearingY();
//
// if (minHeight > minY) minHeight = minY;
// if (maxHeight < maxY) maxHeight = maxY;
//
// uint charWidth = 0;
//
// if (j < (numCharacters - 1))
// {
// charWidth = advance(character, text[j + 1]);
// }
// else
// {
// charWidth = glyph->width() + glyph->horizontalBearingX();
// }
//
// textBB.x() += charWidth;
// }
//
// if (maxHeight < minHeight)
// {
// return Vec2ui(0,0);
// }
//
// textBB.y() = static_cast<uint>(maxHeight - minHeight);
//
// return textBB;
} // namespace cvf

View File

@ -43,8 +43,11 @@ public:
virtual ref<Glyph> getGlyph(wchar_t character) = 0;
virtual uint advance(wchar_t character, wchar_t nextCharacter) = 0;
virtual bool isEmpty() = 0;
float lineSpacing();
Vec2ui textExtent(const String& text);
};
} // namespace cvf

View File

@ -32,11 +32,11 @@ namespace cvf {
//==================================================================================================
///
/// \class cvf::FrameBufferObject
/// \class cvf::FramebufferObject
/// \ingroup Render
///
/// Encapsulates FBOs which are used to redirect OpenGL (and thus shader) output from the default
/// Window Framebuffer to a number of custom buffers (either textures or RenderBuffers
/// Window Framebuffer to a number of custom buffers (either textures or renderbuffers)
///
//==================================================================================================
@ -232,7 +232,7 @@ void FramebufferObject::applyOpenGL(OpenGLContext* oglContext)
createdNewFrameBuffer = true;
}
glBindFramebuffer(GL_FRAMEBUFFER, OglRc::safeOglId(m_oglRcBuffer.p()));
bind(oglContext);
bool attachmentsModified = createdNewFrameBuffer;
@ -419,7 +419,11 @@ void FramebufferObject::applyOpenGL(OpenGLContext* oglContext)
}
}
#ifndef CVF_OPENGL_ES
glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, m_depthStencilRenderBuffer->renderbufferOglId());
#else
CVF_FAIL_MSG("Not supported on iOS");
#endif
m_depthAttachmentVersionTick = m_depthStencilRenderBuffer->versionTick();
}
@ -439,7 +443,11 @@ void FramebufferObject::applyOpenGL(OpenGLContext* oglContext)
if (m_depthStencilTexture2d->textureType() == Texture::TEXTURE_2D)
{
#ifndef CVF_OPENGL_ES
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_TEXTURE_2D, m_depthStencilTexture2d->textureOglId(), 0);
#else
CVF_FAIL_MSG("Not supported on iOS");
#endif
}
else if (m_depthStencilTexture2d->textureType() == Texture::TEXTURE_RECTANGLE)
{
@ -462,6 +470,18 @@ void FramebufferObject::applyOpenGL(OpenGLContext* oglContext)
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void FramebufferObject::bind(OpenGLContext* oglContext) const
{
CVF_CALLSITE_OPENGL(oglContext);
CVF_ASSERT(OglRc::safeOglId(m_oglRcBuffer.p()) != 0);
glBindFramebuffer(GL_FRAMEBUFFER, m_oglRcBuffer->oglId());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -475,6 +495,8 @@ void FramebufferObject::useDefaultWindowFramebuffer(OpenGLContext* oglContext)
glBindFramebuffer(GL_FRAMEBUFFER, 0);
glDrawBuffer(GL_BACK);
#endif
CVF_CHECK_OGL(oglContext);
}
@ -564,7 +586,7 @@ bool FramebufferObject::isFramebufferComplete(OpenGLContext* oglContext, String*
{
CVF_CALLSITE_OPENGL(oglContext);
glBindFramebuffer(GL_FRAMEBUFFER, OglRc::safeOglId(m_oglRcBuffer.p()));
bind(oglContext);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE)

View File

@ -57,6 +57,7 @@ public:
void attachDepthStencilTexture2d(Texture* texture);
void applyOpenGL(OpenGLContext* oglContext);
void bind(OpenGLContext* oglContext) const;
static void useDefaultWindowFramebuffer(OpenGLContext* oglContext);
void deleteFramebuffer(OpenGLContext* oglContext);

View File

@ -23,8 +23,9 @@
#include "cvfMath.h"
#include "cvfTextureImage.h"
#include "cvfTexture.h"
#include "cvfRenderState.h"
#include "cvfSampler.h"
#include "cvfRenderStateTextureBindings.h"
#ifndef CVF_OPENGL_ES
#include "cvfTexture2D_FF.h"
#include "cvfRenderState_FF.h"
@ -249,7 +250,7 @@ void Glyph::setupAndBindTexture(OpenGLContext* oglContext, bool software)
#ifndef CVF_OPENGL_ES
if (renderStateType == RenderState::TEXTURE_MAPPING_FF)
{
TextureMapping_FF* texMapping = static_cast<TextureMapping_FF*>(m_textureBindings.p());
RenderStateTextureMapping_FF* texMapping = static_cast<RenderStateTextureMapping_FF*>(m_textureBindings.p());
texMapping->setupTexture(oglContext);
texMapping->applyOpenGL(oglContext);
return;
@ -262,7 +263,7 @@ void Glyph::setupAndBindTexture(OpenGLContext* oglContext, bool software)
{
if (renderStateType == RenderState::TEXTURE_BINDINGS)
{
TextureBindings* texBindings = static_cast<TextureBindings*>(m_textureBindings.p());
RenderStateTextureBindings* texBindings = static_cast<RenderStateTextureBindings*>(m_textureBindings.p());
texBindings->setupTextures(oglContext);
texBindings->applyOpenGL(oglContext);
return;
@ -331,8 +332,8 @@ void Glyph::setupAndBindTexture(OpenGLContext* oglContext, bool software)
texture->setupTexture(oglContext);
texture->setupTextureParams(oglContext);
ref<TextureMapping_FF> textureMapping = new TextureMapping_FF(texture.p());
textureMapping->setTextureFunction(TextureMapping_FF::MODULATE);
ref<RenderStateTextureMapping_FF> textureMapping = new RenderStateTextureMapping_FF(texture.p());
textureMapping->setTextureFunction(RenderStateTextureMapping_FF::MODULATE);
m_textureBindings = textureMapping;
#endif
@ -347,7 +348,7 @@ void Glyph::setupAndBindTexture(OpenGLContext* oglContext, bool software)
ref<Texture> texture = new Texture(m_textureImage.p());
texture->setupTexture(oglContext);
TextureBindings* textureBindings = new TextureBindings(texture.p(), sampler.p(), "dummy");
RenderStateTextureBindings* textureBindings = new RenderStateTextureBindings(texture.p(), sampler.p(), "dummy");
textureBindings->setupTextures(oglContext);
m_textureBindings = textureBindings;

View File

@ -76,7 +76,7 @@ private:
// Texture info
ref<TextureImage> m_textureImage; // Pre-rendered image of m_character
ref<FloatArray> m_textureCoordinates; // Texture coordinates of where in the m_texgtureImage to find the given pre-rendered character
ref<RenderState> m_textureBindings; // For shader based rendering this is a TextureBindings object, while software rendering uses TextureMapping_FF instead
ref<RenderState> m_textureBindings; // For shader based rendering this is a TextureBindings object, while software rendering uses RenderStateTextureMapping_FF instead
};
} // namespace cvf

View File

@ -46,6 +46,8 @@
#include "cvfOpenGLTypes.h"
#include "cvfOverlayAxisCross.h"
#include "cvfOverlayColorLegend.h"
#include "cvfOverlayImage.h"
#include "cvfOverlayScalarMapperLegend.h"
#include "cvfOverlayItem.h"
#include "cvfOverlayTextBox.h"
#include "cvfPrimitiveSet.h"
@ -55,10 +57,26 @@
#include "cvfPrimitiveSetIndexedUIntScoped.h"
#include "cvfRenderbufferObject.h"
#include "cvfRenderState.h"
#include "cvfRenderStateBlending.h"
#include "cvfRenderStateColorMask.h"
#include "cvfRenderStateCullFace.h"
#include "cvfRenderStateDepth.h"
#include "cvfRenderStateFrontFace.h"
#include "cvfRenderStateLine.h"
#include "cvfRenderStatePoint.h"
#include "cvfRenderStatePolygonMode.h"
#include "cvfRenderStatePolygonOffset.h"
#include "cvfRenderStateSet.h"
#include "cvfRenderStateStencil.h"
#include "cvfRenderStateTextureBindings.h"
#include "cvfRenderStateTracker.h"
#include "cvfSampler.h"
#include "cvfScalarMapper.h"
#include "cvfScalarMapperRangeBased.h"
#include "cvfScalarMapperDiscreteLinear.h"
#include "cvfScalarMapperDiscreteLog.h"
#include "cvfScalarMapperContinuousLinear.h"
#include "cvfScalarMapperContinuousLog.h"
#include "cvfScalarMapperUniformLevels.h"
#include "cvfShader.h"
#include "cvfShaderSourceProvider.h"
@ -78,3 +96,4 @@
#include "cvfRenderState_FF.h"
#include "cvfTexture2D_FF.h"
#endif

View File

@ -74,6 +74,17 @@ MatrixState::MatrixState(const Vec2ui& viewportPosition, const Vec2ui& viewportS
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void MatrixState::setViewMatrix(const Mat4d& viewMatrix)
{
m_viewMatrix = Mat4f(viewMatrix);
m_viewProjectionMatrix = m_projectionMatrix*m_viewMatrix;
m_versionTick++;
}
//--------------------------------------------------------------------------------------------------
/// Computes height of a pixel at unit distance in world system
//--------------------------------------------------------------------------------------------------

View File

@ -37,6 +37,8 @@ public:
MatrixState(const Camera& camera);
MatrixState(const Vec2ui& viewportPosition, const Vec2ui& viewportSize, const Mat4d& projectionMatrix, const Mat4d& viewMatrix);
void setViewMatrix(const Mat4d& viewMatrix);
void setModelMatrix(const Mat4d& modelMatrix);
void clearModelMatrix();

View File

@ -74,6 +74,33 @@ OpenGLCapabilities& OpenGLCapabilities::operator=(const OpenGLCapabilities& rhs)
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool OpenGLCapabilities::operator==(const OpenGLCapabilities& rhs) const
{
if (m_capabilityFlags == rhs.m_capabilityFlags &&
m_openGLMajorVersion == rhs.m_openGLMajorVersion &&
m_supportsFixedFunction == rhs.m_supportsFixedFunction)
{
return true;
}
else
{
return false;
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool OpenGLCapabilities::operator!=(const OpenGLCapabilities& rhs) const
{
return !(*this == rhs);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------

View File

@ -48,6 +48,8 @@ public:
~OpenGLCapabilities();
OpenGLCapabilities& operator=(const OpenGLCapabilities& rhs);
bool operator==(const OpenGLCapabilities& rhs) const;
bool operator!=(const OpenGLCapabilities& rhs) const;
bool hasCapability(Capability capability) const;
void addCapablity(Capability capability);

View File

@ -255,12 +255,12 @@ void OverlayAxisCross::renderAxisImmediateMode(OpenGLContext* oglContext, const
m_axis->renderImmediateMode(oglContext, matrixState);
// Draw X axis triangle
Material_FF xMaterial(Material_FF::PURE_RED);
RenderStateMaterial_FF xMaterial(RenderStateMaterial_FF::PURE_RED);
xMaterial.applyOpenGL(oglContext);
m_xAxisTriangle->renderImmediateMode(oglContext, matrixState);
// Draw Y axis triangle
Material_FF yMaterial(Material_FF::PURE_GREEN);
RenderStateMaterial_FF yMaterial(RenderStateMaterial_FF::PURE_GREEN);
yMaterial.applyOpenGL(oglContext);
m_yAxisTriangle->renderImmediateMode(oglContext, matrixState);
#endif // CVF_OPENGL_ES

View File

@ -35,13 +35,12 @@
#include "cvfMatrixState.h"
#include "cvfBufferObjectManaged.h"
#include "cvfGlyph.h"
#include "cvfRenderStateDepth.h"
#include "cvfRenderStateLine.h"
#ifndef CVF_OPENGL_ES
#include "cvfRenderState_FF.h"
#else
#include "cvfRenderState.h"
#endif
#include "cvfLegendScalarMapper.h"
namespace cvf {
@ -61,11 +60,17 @@ namespace cvf {
OverlayColorLegend::OverlayColorLegend(Font* font)
: m_sizeHint(200, 200),
m_color(Color3::BLACK),
m_lineColor(Color3::BLACK),
m_lineWidth(1),
m_font(font)
{
CVF_ASSERT(font);
CVF_ASSERT(!font->isEmpty());
m_levelColors.reserve(2);
m_levelColors.add(Color3::RED);
m_levelColors.add(Color3::BLUE);
m_tickValues.reserve(3);
m_tickValues.add(0.0);
m_tickValues.add(0.5);
@ -112,17 +117,13 @@ cvf::Vec2ui OverlayColorLegend::minimumSize()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayColorLegend::setScalarMapper(const LegendScalarMapper* scalarMapper)
void OverlayColorLegend::configureLevels(const Color3ubArray& levelColors, const DoubleArray& tickValues)
{
m_scalarMapper = scalarMapper;
if (m_scalarMapper.notNull())
{
std::vector<double> levelValues;
m_scalarMapper->majorLevels(&levelValues);
CVF_ASSERT(levelColors.size() > 0);
CVF_ASSERT(levelColors.size() + 1 == tickValues.size());
m_tickValues.assign(levelValues);
}
m_levelColors = levelColors;
m_tickValues = tickValues;
}
@ -153,6 +154,8 @@ const Color3f& OverlayColorLegend::color() const
}
//--------------------------------------------------------------------------------------------------
/// Set the title (text that will be rendered above the legend)
///
@ -210,6 +213,32 @@ void OverlayColorLegend::renderSoftware(OpenGLContext* oglContext, const Vec2ui&
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool OverlayColorLegend::pick(uint oglXCoord, uint oglYCoord, const Vec2ui& position, const Vec2ui& size)
{
Rectui oglRect(position, size.x(), size.y());
OverlayColorLegendLayoutInfo layoutInViewPortCoords(oglRect.min(), Vec2ui(oglRect.width(), oglRect.height()));
layoutInfo(&layoutInViewPortCoords);
Vec2ui legendBarOrigin = oglRect.min();
legendBarOrigin.x() += static_cast<uint>(layoutInViewPortCoords.legendRect.min().x());
legendBarOrigin.y() += static_cast<uint>(layoutInViewPortCoords.legendRect.min().y());
Rectui legendBarRect = Rectui(legendBarOrigin, static_cast<uint>(layoutInViewPortCoords.legendRect.width()), static_cast<uint>(layoutInViewPortCoords.legendRect.height()));
if ((oglXCoord > legendBarRect.min().x()) && (oglXCoord < legendBarRect.max().x()) &&
(oglYCoord > legendBarRect.min().y()) && (oglYCoord < legendBarRect.max().y()))
{
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
/// Set up camera/viewport and render
//--------------------------------------------------------------------------------------------------
@ -277,7 +306,7 @@ void OverlayColorLegend::setupTextDrawer(TextDrawer* textDrawer, OverlayColorLeg
float textY = static_cast<float>(layout->legendRect.min().y() + layout->tickPixelPos->get(it));
// Always draw first and last tick label. For all others, skip drawing if text ends up
// on top of the previous label.
// on top of the previous label
if (it != 0 && it != (numTicks - 1))
{
if (cvf::Math::abs(textY - lastVisibleTextY) < overlapTolerance)
@ -285,15 +314,6 @@ void OverlayColorLegend::setupTextDrawer(TextDrawer* textDrawer, OverlayColorLeg
m_visibleTickLabels.push_back(false);
continue;
}
// Make sure it does not overlap the last tick as well
float lastTickY = static_cast<float>(layout->legendRect.max().y() );
if (cvf::Math::abs(textY - lastTickY) < overlapTolerance)
{
m_visibleTickLabels.push_back(false);
continue;
}
}
double tickValue = m_tickValues[it];
@ -328,7 +348,7 @@ void OverlayColorLegend::renderLegend(OpenGLContext* oglContext, OverlayColorLeg
CVF_TIGHT_ASSERT(layout->size.x() > 0);
CVF_TIGHT_ASSERT(layout->size.y() > 0);
Depth depth(false);
RenderStateDepth depth(false);
depth.applyOpenGL(oglContext);
// All vertices. Initialized here to set Z to zero once and for all.
@ -338,22 +358,25 @@ void OverlayColorLegend::renderLegend(OpenGLContext* oglContext, OverlayColorLeg
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f
};
// Per vector convenience pointers
float* v0 = &vertexArray[0];
float* v1 = &vertexArray[3];
float* v2 = &vertexArray[6];
float* v3 = &vertexArray[9];
float* v4 = &vertexArray[12];
float* v1 = &vertexArray[0]; // x0, y0
float* v2 = &vertexArray[3]; // x1, y0
float* v3 = &vertexArray[6]; // tickX, y0
float* v4 = &vertexArray[9]; // x0, y1
float* v5 = &vertexArray[12]; // x1, y1
float* v6 = &vertexArray[15]; // tickX, y1
// Constant coordinates
v0[0] = v3[0] = layout->x0;
v1[0] = v4[0] = layout->x1;
v1[0] = v4[0] = layout->x0;
v2[0] = v5[0] = layout->x1;
// Connects
static const ushort trianglesConnects[] = { 0, 1, 4, 0, 4, 3 };
static const ushort linesConnects[] = { 0, 3, 1, 4, 0, 2, 3, 5 };
ref<ShaderProgram> shaderProgram = oglContext->resourceManager()->getLinkedUnlitColorShaderProgram(oglContext);
CVF_TIGHT_ASSERT(shaderProgram.notNull());
@ -368,98 +391,49 @@ void OverlayColorLegend::renderLegend(OpenGLContext* oglContext, OverlayColorLeg
glEnableVertexAttribArray(ShaderProgram::VERTEX);
glVertexAttribPointer(ShaderProgram::VERTEX, 3, GL_FLOAT, GL_FALSE, 0, vertexArray);
// Render color bar as one colored quad per pixel
int legendHeightPixelCount = static_cast<int>(layout->tickPixelPos->get(m_tickValues.size()-1) - layout->tickPixelPos->get(0) + 0.01);
if (m_scalarMapper.notNull())
// Render colored quads and lines
size_t numColors = m_levelColors.size();
CVF_ASSERT(numColors == m_tickValues.size() - 1);
size_t ic;
for (ic = 0; ic < numColors; ic++)
{
int iPx;
for (iPx = 0; iPx < legendHeightPixelCount; iPx++)
const Color3ub& clr = m_levelColors[ic];
float y0 = static_cast<float>(layout->legendRect.min().y() + layout->tickPixelPos->get(ic));
float y1 = static_cast<float>(layout->legendRect.min().y() + layout->tickPixelPos->get(ic + 1));
// Dynamic coordinates for rectangle
v1[1] = v2[1] = y0;
v4[1] = v5[1] = y1;
// Dynamic coordinates for tickmarks-lines
v3[0] = m_visibleTickLabels[ic] ? layout->tickX : layout->x1;
v6[0] = m_visibleTickLabels[ic + 1] ? layout->tickX : layout->x1;
v3[1] = y0;
v6[1] = y1;
// Draw filled rectangle elements
{
const Color3ub& clr = m_scalarMapper->mapToColor(m_scalarMapper->domainValue((iPx+0.5)/legendHeightPixelCount));
float y0 = static_cast<float>(layout->legendRect.min().y() + iPx);
float y1 = static_cast<float>(layout->legendRect.min().y() + iPx + 1);
// Dynamic coordinates for rectangle
v0[1] = v1[1] = y0;
v3[1] = v4[1] = y1;
// Draw filled rectangle elements
{
UniformFloat uniformColor("u_color", Color4f(Color3f(clr)));
shaderProgram->applyUniform(oglContext, uniformColor);
UniformFloat uniformColor("u_color", Color4f(Color3f(clr)));
shaderProgram->applyUniform(oglContext, uniformColor);
#ifdef CVF_OPENGL_ES
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, trianglesConnects);
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, trianglesConnects);
#else
glDrawRangeElements(GL_TRIANGLES, 0, 4, 6, GL_UNSIGNED_SHORT, trianglesConnects);
glDrawRangeElements(GL_TRIANGLES, 0, 4, 6, GL_UNSIGNED_SHORT, trianglesConnects);
#endif
}
}
}
// Render frame
// Dynamic coordinates for tickmarks-lines
bool isRenderingFrame = true;
if (isRenderingFrame)
{
v0[0] = v2[0] = layout->legendRect.min().x()-0.5f;
v1[0] = v3[0] = layout->legendRect.max().x()-0.5f;
v0[1] = v1[1] = layout->legendRect.min().y()-0.5f;
v2[1] = v3[1] = layout->legendRect.max().y()-0.5f;
static const ushort frameConnects[] = { 0, 1, 1, 3, 3, 2, 2, 0};
UniformFloat uniformColor("u_color", Color4f(m_color));
shaderProgram->applyUniform(oglContext, uniformColor);
#ifdef CVF_OPENGL_ES
glDrawElements(GL_LINES, 8, GL_UNSIGNED_SHORT, frameConnects);
#else
glDrawRangeElements(GL_LINES, 0, 3, 8, GL_UNSIGNED_SHORT, frameConnects);
#endif
}
// Render tickmarks
bool isRenderingTicks = true;
if (isRenderingTicks)
{
// Constant coordinates
v0[0] = layout->x0;
v1[0] = layout->x1 - 0.5f*(layout->tickX - layout->x1) - 0.5f;
v2[0] = layout->x1;
v3[0] = layout->tickX - 0.5f*(layout->tickX - layout->x1) - 0.5f;
v4[0] = layout->tickX;
static const ushort tickLinesWithLabel[] = { 0, 4 };
static const ushort tickLinesWoLabel[] = { 2, 3 };
size_t ic;
for (ic = 0; ic < m_tickValues.size(); ic++)
// Draw legend lines
{
float y0 = static_cast<float>(layout->legendRect.min().y() + layout->tickPixelPos->get(ic) - 0.5f);
// Dynamic coordinates for tickmarks-lines
v0[1] = v1[1] = v2[1] = v3[1] = v4[1] = y0;
UniformFloat uniformColor("u_color", Color4f(m_color));
shaderProgram->applyUniform(oglContext, uniformColor);
const ushort * linesConnects;
if ( m_visibleTickLabels[ic])
{
linesConnects = tickLinesWithLabel;
}
else
{
linesConnects = tickLinesWoLabel;
}
RenderStateLine line(static_cast<float>(m_lineWidth));
line.applyOpenGL(oglContext);
UniformFloat uniformColor("u_color", Color4f(m_lineColor));
shaderProgram->applyUniform(oglContext, uniformColor);
#ifdef CVF_OPENGL_ES
glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, linesConnects);
glDrawElements(GL_LINES, 8, GL_UNSIGNED_SHORT, linesConnects);
#else
glDrawRangeElements(GL_LINES, 0, 4, 2, GL_UNSIGNED_SHORT, linesConnects);
glDrawRangeElements(GL_LINES, 0, 5, 8, GL_UNSIGNED_SHORT, linesConnects);
#endif
}
}
@ -470,9 +444,12 @@ void OverlayColorLegend::renderLegend(OpenGLContext* oglContext, OverlayColorLeg
shaderProgram->useNoProgram(oglContext);
// Reset render states
Depth resetDepth;
RenderStateDepth resetDepth;
resetDepth.applyOpenGL(oglContext);
RenderStateLine resetLine;
resetLine.applyOpenGL(oglContext);
CVF_CHECK_OGL(oglContext);
}
@ -490,10 +467,10 @@ void OverlayColorLegend::renderLegendImmediateMode(OpenGLContext* oglContext, Ov
CVF_TIGHT_ASSERT(layout->size.x() > 0);
CVF_TIGHT_ASSERT(layout->size.y() > 0);
Depth depth(false);
RenderStateDepth depth(false);
depth.applyOpenGL(oglContext);
Lighting_FF lighting(false);
RenderStateLighting_FF lighting(false);
lighting.applyOpenGL(oglContext);
// All vertices. Initialized here to set Z to zero once and for all.
@ -504,111 +481,68 @@ void OverlayColorLegend::renderLegendImmediateMode(OpenGLContext* oglContext, Ov
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f
};
// Per vector convenience pointers
float* v0 = &vertexArray[0];
float* v1 = &vertexArray[3];
float* v2 = &vertexArray[6];
float* v3 = &vertexArray[9];
float* v4 = &vertexArray[12];
float* v1 = &vertexArray[0]; // x0, y0
float* v2 = &vertexArray[3]; // x1, y0
float* v3 = &vertexArray[6]; // tickX, y0
float* v4 = &vertexArray[9]; // x0, y1
float* v5 = &vertexArray[12]; // x1, y1
float* v6 = &vertexArray[15]; // tickX, y1
// Constant coordinates
v0[0] = v3[0] = layout->x0;
v1[0] = v4[0] = layout->x1;
v1[0] = v4[0] = layout->x0;
v2[0] = v5[0] = layout->x1;
// Render color bar as one colored quad per pixel
int legendHeightPixelCount = static_cast<int>(layout->tickPixelPos->get(m_tickValues.size() - 1) - layout->tickPixelPos->get(0) + 0.01);
if (m_scalarMapper.notNull())
// Render colored quads and lines
size_t numColors = m_levelColors.size();
CVF_ASSERT(numColors == m_tickValues.size() - 1);
size_t ic;
for (ic = 0; ic < numColors; ic++)
{
int iPx;
for (iPx = 0; iPx < legendHeightPixelCount; iPx++)
{
const Color3ub& clr = m_scalarMapper->mapToColor(m_scalarMapper->domainValue((iPx+0.5)/legendHeightPixelCount));
float y0 = static_cast<float>(layout->legendRect.min().y() + iPx);
float y1 = static_cast<float>(layout->legendRect.min().y() + iPx + 1);
const Color3ub& levelColor = m_levelColors[ic];
float y0 = static_cast<float>(layout->margins.y() + layout->tickPixelPos->get(ic));
float y1 = static_cast<float>(layout->margins.y() + layout->tickPixelPos->get(ic + 1));
// Dynamic coordinates for rectangle
v0[1] = v1[1] = y0;
v3[1] = v4[1] = y1;
// Dynamic coordinates for rectangle
v1[1] = v2[1] = y0;
v4[1] = v5[1] = y1;
// Draw filled rectangle elements
glColor3ubv(clr.ptr());
glBegin(GL_TRIANGLE_FAN);
glVertex3fv(v0);
glVertex3fv(v1);
glVertex3fv(v4);
glVertex3fv(v3);
glEnd();
}
}
// Dynamic coordinates for tickmarks-lines
v3[0] = m_visibleTickLabels[ic] ? layout->tickX : layout->x1;
v6[0] = m_visibleTickLabels[ic + 1] ? layout->tickX : layout->x1;
v3[1] = y0;
v6[1] = y1;
// Render frame
// Dynamic coordinates for tickmarks-lines
bool isRenderingFrame = true;
if (isRenderingFrame)
{
v0[0] = v2[0] = layout->legendRect.min().x()-0.5f;
v1[0] = v3[0] = layout->legendRect.max().x()-0.5f;
v0[1] = v1[1] = layout->legendRect.min().y()-0.5f;
v2[1] = v3[1] = layout->legendRect.max().y()-0.5f;
glColor3fv(m_color.ptr());
glBegin(GL_LINES);
glVertex3fv(v0);
// Draw filled rectangle elements
glColor3ubv(levelColor.ptr());
glBegin(GL_TRIANGLE_FAN);
glVertex3fv(v1);
glVertex3fv(v1);
glVertex3fv(v3);
glVertex3fv(v3);
glVertex3fv(v2);
glVertex3fv(v2);
glVertex3fv(v0);
glVertex3fv(v5);
glVertex3fv(v4);
glEnd();
}
// Render tickmarks
bool isRenderingTicks = true;
if (isRenderingTicks)
{
// Constant coordinates
v0[0] = layout->x0;
v1[0] = layout->x1 - 0.5f*(layout->tickX - layout->x1) - 0.5f;
v2[0] = layout->x1;
v3[0] = layout->tickX - 0.5f*(layout->tickX - layout->x1) - 0.5f;
v4[0] = layout->tickX;
size_t ic;
for (ic = 0; ic < m_tickValues.size(); ic++)
{
float y0 = static_cast<float>(layout->legendRect.min().y() + layout->tickPixelPos->get(ic) - 0.5f);
// Dynamic coordinates for tickmarks-lines
v0[1] = v1[1] = v2[1] = v3[1] = v4[1] = y0;
glColor3fv(m_color.ptr());
glBegin(GL_LINES);
if ( m_visibleTickLabels[ic])
{
glVertex3fv(v0);
glVertex3fv(v4);
}
else
{
glVertex3fv(v2);
glVertex3fv(v3);
}
glEnd();
}
// Draw legend lines
glColor3fv(m_color.ptr());
glBegin(GL_LINES);
glVertex3fv(v1);
glVertex3fv(v4);
glVertex3fv(v2);
glVertex3fv(v5);
glVertex3fv(v1);
glVertex3fv(v3);
glVertex3fv(v4);
glVertex3fv(v6);
glEnd();
}
// Reset render states
Lighting_FF resetLighting;
RenderStateLighting_FF resetLighting;
resetLighting.applyOpenGL(oglContext);
Depth resetDepth;
RenderStateDepth resetDepth;
resetDepth.applyOpenGL(oglContext);
CVF_CHECK_OGL(oglContext);
@ -641,22 +575,79 @@ void OverlayColorLegend::layoutInfo(OverlayColorLegendLayoutInfo* layout)
layout->x1 = layout->margins.x() + layout->legendRect.width();
layout->tickX = layout->x1 + 5;
// Build array containing the pixel positions of all the ticks
size_t numTicks = m_tickValues.size();
layout->tickPixelPos = new DoubleArray(numTicks);
size_t i;
for (i = 0; i < numTicks; i++)
if (numTicks < 1)
{
double t;
if (m_scalarMapper.isNull()) t = 0;
else t = m_scalarMapper->normalizedLevelPosition(m_tickValues[i]);
t = Math::clamp(t, 0.0, 1.1);
layout->tickPixelPos->set(i, t*layout->legendRect.height());
return;
}
// Get legend range (the slightly odd test on the range should guard against any NaNs
double minVal = m_tickValues[0];
double maxVal = m_tickValues[numTicks - 1];
double valueRange = (maxVal - minVal);
if (!(valueRange >= 0))
{
layout->tickPixelPos = NULL;
return;
}
// Build array containing the pixel positions of all the ticks
layout->tickPixelPos = new DoubleArray(numTicks);
if (valueRange > 0)
{
size_t i;
for (i = 0; i < numTicks; i++)
{
double t = (m_tickValues[i] - minVal)/valueRange;
t = Math::clamp(t, 0.0, 1.1);
layout->tickPixelPos->set(i, t*layout->legendRect.height());
}
}
else
{
size_t i;
for (i = 0; i < numTicks; i++)
{
layout->tickPixelPos->set(i, static_cast<double>(i)*(layout->legendRect.height()/static_cast<double>(numTicks)));
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayColorLegend::setLineColor(const Color3f& lineColor)
{
m_lineColor = lineColor;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const Color3f& OverlayColorLegend::lineColor() const
{
return m_lineColor;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayColorLegend::setLineWidth(int lineWidth)
{
m_lineWidth = lineWidth;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int OverlayColorLegend::lineWidth() const
{
return m_lineWidth;
}
} // namespace cvf

View File

@ -31,7 +31,6 @@ class Font;
class ShaderProgram;
class MatrixState;
class TextDrawer;
class LegendScalarMapper;
//==================================================================================================
@ -76,16 +75,22 @@ public:
virtual Vec2ui sizeHint();
virtual Vec2ui maximumSize();
virtual Vec2ui minimumSize();
void setScalarMapper(const LegendScalarMapper* scalarMapper);
virtual void render(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size);
virtual void renderSoftware(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size);
virtual bool pick(uint oglXCoord, uint oglYCoord, const Vec2ui& position, const Vec2ui& size);
void configureLevels(const Color3ubArray& levelColors, const DoubleArray& tickValues);
void setSizeHint(const Vec2ui& size);
void setColor(const Color3f& color);
const Color3f& color() const;
void setLineColor(const Color3f& lineColor);
const Color3f& lineColor() const;
void setLineWidth(int lineWidth);
int lineWidth() const;
void setTitle(const String& title);
String title() const;
@ -99,16 +104,17 @@ protected:
void layoutInfo(OverlayColorLegendLayoutInfo* layout);
protected:
Color3ubArray m_levelColors; // Colors for n levels
DoubleArray m_tickValues; // Ticks between each level + top and bottom of legend (n+1 entries)
std::vector<bool> m_visibleTickLabels; // Skip tick labels ending up on top of previous visible label
Vec2ui m_sizeHint; // Pixel size of the color legend area
Color3f m_color;
Color3f m_lineColor;
int m_lineWidth;
std::vector<String> m_titleStrings;
ref<Font> m_font;
cref<LegendScalarMapper> m_scalarMapper;
};
}

View File

@ -0,0 +1,317 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfOverlayImage.h"
#include "cvfMatrixState.h"
#include "cvfCamera.h"
#include "cvfShaderProgram.h"
#include "cvfOpenGL.h"
#include "cvfViewport.h"
#include "cvfOpenGLResourceManager.h"
#include "cvfUniform.h"
#include "cvfTextureImage.h"
#include "cvfSampler.h"
#include "cvfTexture.h"
#include "cvfShaderProgramGenerator.h"
#include "cvfShaderSourceRepository.h"
#include "cvfShaderSourceProvider.h"
#include "cvfShaderProgram.h"
#include "cvfRenderStateDepth.h"
#include "cvfRenderStateTextureBindings.h"
#include "cvfRenderStateBlending.h"
#ifndef CVF_OPENGL_ES
#include "cvfRenderState_FF.h"
#endif
namespace cvf {
//==================================================================================================
///
/// \class cvf::OverlayImage
/// \ingroup Render
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Constructor. The specified font is used to draw all the text
//--------------------------------------------------------------------------------------------------
OverlayImage::OverlayImage(TextureImage* image)
: m_alpha(1.0f)
{
CVF_ASSERT(image);
m_size.x() = image->width();
m_size.y() = image->height();
m_blendMode = NO_BLENDING;
m_sampler = new cvf::Sampler;
m_sampler->setWrapMode(cvf::Sampler::CLAMP_TO_EDGE);
m_sampler->setMinFilter(cvf::Sampler::NEAREST);
m_sampler->setMagFilter(cvf::Sampler::NEAREST);
setImage(image);
}
//--------------------------------------------------------------------------------------------------
/// Destructor
//--------------------------------------------------------------------------------------------------
OverlayImage::~OverlayImage()
{
}
//--------------------------------------------------------------------------------------------------
/// Returns the wanted size in pixels
//--------------------------------------------------------------------------------------------------
cvf::Vec2ui OverlayImage::sizeHint()
{
return m_size;
}
//--------------------------------------------------------------------------------------------------
/// Returns the maximum size of the text box in pixels
//--------------------------------------------------------------------------------------------------
cvf::Vec2ui OverlayImage::maximumSize()
{
return sizeHint();
}
//--------------------------------------------------------------------------------------------------
/// Returns the minimum size of the text box in pixels
//--------------------------------------------------------------------------------------------------
cvf::Vec2ui OverlayImage::minimumSize()
{
return sizeHint();
}
//--------------------------------------------------------------------------------------------------
/// Render using Shaders
//--------------------------------------------------------------------------------------------------
void OverlayImage::render(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size)
{
render(oglContext, position, size, false);
}
//--------------------------------------------------------------------------------------------------
/// Render using Fixed Function
//--------------------------------------------------------------------------------------------------
void OverlayImage::renderSoftware(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size)
{
render(oglContext, position, size, true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayImage::render(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size, bool software)
{
CVF_CALLSITE_OPENGL(oglContext);
Camera projCam;
projCam.setViewport(position.x(), position.y(), size.x(), size.y());
projCam.setProjectionAsPixelExact2D();
projCam.setViewMatrix(Mat4d::IDENTITY);
// Turn off depth test
RenderStateDepth depth(false, RenderStateDepth::LESS, false);
depth.applyOpenGL(oglContext);
float vertexArray[12];
float textureCoords[] = {0.0f, 0.0f,
1.0f, 0.0f,
1.0f, 1.0f,
0.0f, 1.0f};
projCam.viewport()->applyOpenGL(oglContext, Viewport::DO_NOT_CLEAR);
if (software)
{
if (ShaderProgram::supportedOpenGL(oglContext))
{
ShaderProgram::useNoProgram(oglContext);
}
#ifndef CVF_OPENGL_ES
RenderStateMaterial_FF mat;
mat.enableColorMaterial(true);
mat.applyOpenGL(oglContext);
RenderStateLighting_FF light(false);
light.applyOpenGL(oglContext);
#endif
projCam.applyOpenGL();
}
else
{
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(ShaderProgram::VERTEX);
glEnableVertexAttribArray(ShaderProgram::TEX_COORD_2F_0);
glVertexAttribPointer(ShaderProgram::VERTEX, 3, GL_FLOAT, GL_FALSE, 0, vertexArray);
glVertexAttribPointer(ShaderProgram::TEX_COORD_2F_0, 2, GL_FLOAT, GL_FALSE, 0, textureCoords);
if (m_shaderProgram.isNull())
{
ShaderProgramGenerator gen("OverlayImage_Shader", ShaderSourceProvider::instance());
gen.addVertexCode(ShaderSourceRepository::vs_MinimalTexture);
if (m_blendMode == GLOBAL_ALPHA)
{
gen.addFragmentCode(ShaderSourceRepository::src_TextureGlobalAlpha);
}
else
{
gen.addFragmentCode(ShaderSourceRepository::src_Texture);
}
gen.addFragmentCode(ShaderSourceRepository::fs_Unlit);
m_shaderProgram = gen.generate();
m_shaderProgram->linkProgram(oglContext);
}
if (m_shaderProgram->useProgram(oglContext))
{
MatrixState projMatrixState(projCam);
m_shaderProgram->clearUniformApplyTracking();
m_shaderProgram->applyFixedUniforms(oglContext, projMatrixState);
}
}
Vec3f min(1.0f, 1.0f, 0.0f);
Vec3f max(static_cast<float>(size.x() - 1), static_cast<float>(size.y() - 1), 0.0f);
// Setup the vertex array
float* v1 = &vertexArray[0];
float* v2 = &vertexArray[3];
float* v3 = &vertexArray[6];
float* v4 = &vertexArray[9];
v1[0] = min.x(); v1[1] = min.y(); v1[2] = 0.0f;
v2[0] = max.x(); v2[1] = min.y(); v2[2] = 0.0f;
v3[0] = max.x(); v3[1] = max.y(); v3[2] = 0.0f;
v4[0] = min.x(); v4[1] = max.y(); v4[2] = 0.0f;
if (m_texture->textureOglId() == 0)
{
m_texture->setupTexture(oglContext);
}
if (m_blendMode != NO_BLENDING)
{
RenderStateBlending blend;
blend.configureTransparencyBlending();
blend.applyOpenGL(oglContext);
}
m_textureBindings->applyOpenGL(oglContext);
if (software)
{
#ifndef CVF_OPENGL_ES
glColor4f(1.0f, 1.0f, 1.0f, m_alpha);
glBegin(GL_TRIANGLE_FAN);
glTexCoord2f(textureCoords[0], textureCoords[1]);
glVertex3fv(v1);
glTexCoord2f(textureCoords[2], textureCoords[3]);
glVertex3fv(v2);
glTexCoord2f(textureCoords[4], textureCoords[5]);
glVertex3fv(v3);
glTexCoord2f(textureCoords[6], textureCoords[7]);
glVertex3fv(v4);
glEnd();
#endif
}
else
{
if (m_blendMode == GLOBAL_ALPHA)
{
UniformFloat alphaUniform("u_alpha", m_alpha);
m_shaderProgram->applyUniform(oglContext, alphaUniform);
}
glDrawArrays(GL_TRIANGLE_FAN, 0, 4);
}
if (m_blendMode != NO_BLENDING)
{
RenderStateBlending blend;
blend.applyOpenGL(oglContext);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayImage::setImage(TextureImage* image)
{
m_image = image;
m_texture = new Texture(image);
m_textureBindings = new cvf::RenderStateTextureBindings;
m_textureBindings->addBinding(m_texture.p(), m_sampler.p(), "u_texture2D");
}
//--------------------------------------------------------------------------------------------------
/// Set the size (in pixels) of the text box
//--------------------------------------------------------------------------------------------------
void OverlayImage::setPixelSize( const Vec2ui& size )
{
m_size = size;
}
//--------------------------------------------------------------------------------------------------
/// Returns the text shown in the text box
//--------------------------------------------------------------------------------------------------
const TextureImage* OverlayImage::image() const
{
return m_image.p();
}
//--------------------------------------------------------------------------------------------------
/// Set the transparency of the image. 1.0 = opaque, 0.0 = invisible
//--------------------------------------------------------------------------------------------------
void OverlayImage::setGlobalAlpha(float alphaFactor)
{
m_alpha = alphaFactor;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayImage::setBlending(Blending mode)
{
m_blendMode = mode;
}
} // namespace cvf

View File

@ -0,0 +1,80 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#pragma once
#include "cvfOverlayItem.h"
namespace cvf {
class TextureImage;
class Sampler;
class RenderStateTextureBindings;
class Texture;
class ShaderProgram;
//==================================================================================================
//
// Overlay text box
//
//==================================================================================================
class OverlayImage : public OverlayItem
{
public:
enum Blending
{
NO_BLENDING,
GLOBAL_ALPHA,
TEXTURE_ALPHA
};
public:
OverlayImage(TextureImage* image);
~OverlayImage();
virtual Vec2ui sizeHint();
virtual Vec2ui maximumSize();
virtual Vec2ui minimumSize();
virtual void render(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size);
virtual void renderSoftware(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size);
void setImage(TextureImage* image);
void setPixelSize(const Vec2ui& size);
void setGlobalAlpha(float alphaFactor);
void setBlending(Blending mode);
const TextureImage* image() const;
private:
void render(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size, bool software);
private:
Vec2ui m_size;
ref<TextureImage> m_image;
ref<Sampler> m_sampler;
ref<RenderStateTextureBindings> m_textureBindings;
ref<Texture> m_texture;
ref<ShaderProgram> m_shaderProgram;
Blending m_blendMode;
float m_alpha;
};
}

View File

@ -0,0 +1,62 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfOverlayTextBox.h"
#include "cvfDrawableText.h"
#include "cvfMatrixState.h"
#include "cvfCamera.h"
#include "cvfShaderProgram.h"
#include "cvfOpenGL.h"
#include "cvfViewport.h"
#include "cvfOpenGLResourceManager.h"
#include "cvfUniform.h"
#ifndef CVF_OPENGL_ES
#include "cvfRenderState_FF.h"
#endif
namespace cvf {
//==================================================================================================
///
/// \class cvf::OverlayItem
/// \ingroup Render
///
/// A base class for all overlay items
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Do hit test on the overlay item. Base class only does a check
//--------------------------------------------------------------------------------------------------
bool OverlayItem::pick(uint oglXCoord, uint oglYCoord, const Vec2ui& position, const Vec2ui& size)
{
Rectui oglRect(position, size.x(), size.y());
if ((oglXCoord > oglRect.min().x()) && (oglXCoord < oglRect.max().x()) &&
(oglYCoord > oglRect.min().y()) && (oglYCoord < oglRect.max().y()))
{
return true;
}
return false;
}
} // namespace cvf

View File

@ -21,6 +21,7 @@
#include "cvfObject.h"
#include "cvfVector2.h"
#include "cvfRect.h"
namespace cvf {
@ -58,6 +59,7 @@ public:
virtual void render(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size) = 0;
virtual void renderSoftware(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size) = 0;
virtual bool pick(uint oglXCoord, uint oglYCoord, const Vec2ui& position, const Vec2ui& size);
};
}

View File

@ -0,0 +1,725 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfOverlayNavigationCube.h"
#include "cvfOpenGL.h"
#include "cvfOpenGLResourceManager.h"
#include "cvfGeometryBuilderDrawableGeo.h"
#include "cvfGeometryUtils.h"
#include "cvfViewport.h"
#include "cvfCamera.h"
#include "cvfTextDrawer.h"
#include "cvfFont.h"
#include "cvfShaderProgram.h"
#include "cvfUniform.h"
#include "cvfMatrixState.h"
#include "cvfDrawableVectors.h"
#include "cvfGeometryBuilderTriangles.h"
#include "cvfArrowGenerator.h"
#include "cvfBufferObjectManaged.h"
#include "cvfDrawableText.h"
#include "cvfTextureImage.h"
#include "cvfPrimitiveSet.h"
#include "cvfPrimitiveSetIndexedUShort.h"
#include "cvfShaderProgramGenerator.h"
#include "cvfShaderSourceProvider.h"
#ifndef CVF_OPENGL_ES
#include "cvfRenderState_FF.h"
#endif
namespace cvf {
//==================================================================================================
///
/// \class cvf::OverlayNavigationCube
/// \ingroup Render
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Constructor
//--------------------------------------------------------------------------------------------------
OverlayNavigationCube::OverlayNavigationCube(Camera* camera, Font* font)
: m_camera(camera),
m_xLabel("ax"),
m_yLabel("by"),
m_zLabel("cz"),
m_textColor(Color3::BLACK),
m_font(font),
m_size(120, 120)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
OverlayNavigationCube::~OverlayNavigationCube()
{
// Empty destructor to avoid errors with undefined types when cvf::ref's destructor gets called
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayNavigationCube::setAxisLabels( const String& xLabel, const String& yLabel, const String& zLabel )
{
// Clipping of axis label text is depends on m_size and
// z-part of axisMatrix.setTranslation(Vec3d(0, 0, -4.4)) defined in OverlayNavigationCube::render()
CVF_ASSERT (xLabel.size() < 5 && yLabel.size() < 5 && zLabel.size() < 5);
m_xLabel = xLabel;
m_yLabel = yLabel;
m_zLabel = zLabel;
}
//--------------------------------------------------------------------------------------------------
/// Set color of the axis labels
//--------------------------------------------------------------------------------------------------
void OverlayNavigationCube::setAxisLabelsColor(const Color3f& color)
{
m_textColor = color;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec2ui OverlayNavigationCube::sizeHint()
{
return m_size;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec2ui OverlayNavigationCube::maximumSize()
{
return sizeHint();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec2ui OverlayNavigationCube::minimumSize()
{
return sizeHint();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayNavigationCube::setSize(const Vec2ui& size)
{
m_size = size;
}
//--------------------------------------------------------------------------------------------------
/// Hardware rendering using shader programs
//--------------------------------------------------------------------------------------------------
void OverlayNavigationCube::render(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size)
{
Mat4d viewMatrix = m_camera->viewMatrix();
render(oglContext, position, size, false, viewMatrix);
}
//--------------------------------------------------------------------------------------------------
/// Software rendering
//--------------------------------------------------------------------------------------------------
void OverlayNavigationCube::renderSoftware(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size)
{
Mat4d viewMatrix = m_camera->viewMatrix();
render(oglContext, position, size, true, viewMatrix);
}
//--------------------------------------------------------------------------------------------------
/// Set up camera/viewport and render
//--------------------------------------------------------------------------------------------------
void OverlayNavigationCube::render(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size, bool software, const Mat4d& viewMatrix)
{
if (size.x() <= 0 || size.y() <= 0)
{
return;
}
if (m_axis.isNull())
{
createAxisGeometry(software);
}
if (m_cubeGeos.size() == 0)
{
createCubeGeos();
// Create the shader for the cube geometry
ShaderProgramGenerator gen("CubeGeoShader", ShaderSourceProvider::instance());
gen.configureStandardHeadlightColor();
m_cubeGeoShader = gen.generate();
m_cubeGeoShader->linkProgram(oglContext);
}
// Position the camera far enough away to make the axis and the text fit within the viewport
Mat4d axisMatrix = viewMatrix;
axisMatrix.setTranslation(Vec3d(0, 0, -2.0));
// Setup camera
Camera cam;
cam.setProjectionAsPerspective(40.0, 0.05, 100.0);
cam.setViewMatrix(axisMatrix);
cam.setViewport(position.x(), position.y(), size.x(), size.y());
// Setup viewport
cam.viewport()->applyOpenGL(oglContext, Viewport::CLEAR_DEPTH);
cam.applyOpenGL();
// Do the actual rendering
// -----------------------------------------------
MatrixState matrixState(cam);
if (software)
{
renderAxisImmediateMode(oglContext, matrixState);
}
else
{
renderAxis(oglContext, matrixState);
}
renderCubeGeos(oglContext, software, matrixState);
renderAxisLabels(oglContext, software, matrixState);
}
//--------------------------------------------------------------------------------------------------
/// Draw the axis
//--------------------------------------------------------------------------------------------------
void OverlayNavigationCube::renderAxis(OpenGLContext* oglContext, const MatrixState& matrixState)
{
CVF_ASSERT(m_axis.notNull());
OpenGLResourceManager* resourceManager = oglContext->resourceManager();
ref<ShaderProgram> vectorProgram = resourceManager->getLinkedVectorDrawerShaderProgram(oglContext);
if (vectorProgram->useProgram(oglContext))
{
vectorProgram->clearUniformApplyTracking();
vectorProgram->applyFixedUniforms(oglContext, matrixState);
}
// Draw X, Y and Z vectors
m_axis->render(oglContext, vectorProgram.p(), matrixState);
}
//--------------------------------------------------------------------------------------------------
/// Draw the axis using immediate mode OpenGL
//--------------------------------------------------------------------------------------------------
void OverlayNavigationCube::renderAxisImmediateMode(OpenGLContext* oglContext, const MatrixState& matrixState)
{
#ifdef CVF_OPENGL_ES
CVF_FAIL_MSG("Not supported on OpenGL ES");
#else
m_axis->renderImmediateMode(oglContext, matrixState);
#endif // CVF_OPENGL_ES
}
//--------------------------------------------------------------------------------------------------
/// Create the geometry used to draw the axis (vector arrows) and the two triangles
//--------------------------------------------------------------------------------------------------
void OverlayNavigationCube::createAxisGeometry(bool software)
{
CVF_ASSERT(m_axis.isNull());
// Axis colors
ref<Color3fArray> colorArray = new Color3fArray;
colorArray->resize(3);
colorArray->set(0, Color3::RED); // X axis
colorArray->set(1, Color3::GREEN); // Y axis
colorArray->set(2, Color3::BLUE); // Z axis
// Positions of the vectors - All in origo
Vec3f cp[8];
navCubeCornerPoints(cp);
ref<cvf::Vec3fArray> vertexArray = new Vec3fArray;
vertexArray->resize(3);
vertexArray->set(0, cp[0]); // X axis
vertexArray->set(1, cp[0]); // Y axis
vertexArray->set(2, cp[0]); // Z axis
// Direction & magnitude of the vectors
ref<cvf::Vec3fArray> vectorArray = new Vec3fArray;
vectorArray->resize(3);
vectorArray->set(0, Vec3f::X_AXIS); // X axis
vectorArray->set(1, Vec3f::Y_AXIS); // Y axis
vectorArray->set(2, Vec3f::Z_AXIS); // Z axis
// Create the arrow glyph for the vector drawer
GeometryBuilderTriangles arrowBuilder;
ArrowGenerator gen;
gen.setShaftRelativeRadius(0.045f);
gen.setHeadRelativeRadius(0.12f);
gen.setHeadRelativeLength(0.2f);
gen.setNumSlices(30);
gen.generate(&arrowBuilder);
if (software)
{
m_axis = new DrawableVectors();
}
else
{
m_axis = new DrawableVectors("u_transformationMatrix", "u_color");
}
m_axis->setVectors(vertexArray.p(), vectorArray.p());
m_axis->setColors(colorArray.p());
m_axis->setGlyph(arrowBuilder.trianglesUShort().p(), arrowBuilder.vertices().p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayNavigationCube::renderCubeGeos(OpenGLContext* oglContext, bool software, const MatrixState& matrixState)
{
CVF_UNUSED(software);
for (size_t i = 0; i < m_cubeGeos.size(); ++i)
{
m_cubeGeos[i]->render(oglContext, m_cubeGeoShader.p(), matrixState);
}
}
//--------------------------------------------------------------------------------------------------
/// Draw the axis labels
//--------------------------------------------------------------------------------------------------
void OverlayNavigationCube::renderAxisLabels(OpenGLContext* oglContext, bool software, const MatrixState& matrixState)
{
// Multiply with 1.08 will slightly pull the labels away from the corresponding arrow head
Vec3f xPos(1.08f, 0, 0);
Vec3f yPos(0, 1.08f, 0);
Vec3f zPos(0, 0, 1.08f);
DrawableText drawableText;
drawableText.setFont(m_font.p());
drawableText.setCheckPosVisible(false);
drawableText.setDrawBorder(false);
drawableText.setDrawBackground(false);
drawableText.setVerticalAlignment(TextDrawer::CENTER);
drawableText.setTextColor(m_textColor);
if (!m_xLabel.isEmpty()) drawableText.addText(m_xLabel, xPos);
if (!m_yLabel.isEmpty()) drawableText.addText(m_yLabel, yPos);
if (!m_zLabel.isEmpty()) drawableText.addText(m_zLabel, zPos);
// Do the actual rendering
// -----------------------------------------------
if (software)
{
drawableText.renderSoftware(oglContext, matrixState);
}
else
{
ref<ShaderProgram> textShader = oglContext->resourceManager()->getLinkedTextShaderProgram(oglContext);
drawableText.render(oglContext, textShader.p(), matrixState);
}
}
//--------------------------------------------------------------------------------------------------
/// Face (with local indices):
/// 7---------6 4 3
/// /| /| |z |---|----------|---|
/// / | / | | / y |TL | TOP |TR |
/// 4---------5 | | / |---|----------|---|
/// | 3------|--2 *---x | | | |
/// | / | / | L | CENTER | R |
/// |/ |/ | | | |
/// 0---------1 |---|----------|---|
/// |BL | BOTTOM |BR |
/// |---|----------|---|
/// 1 2
///
/// Items:
/// Faces:
/// +X : VT_NCI_X_POS : RIGHT : 0 2 6 5
/// -X : VT_NCI_X_NEG : LEFT : 3 0 4 7
/// +Y : VT_NCI_Y_POS : BACK : 2 3 7 6
/// -Y : VT_NCI_Y_NEG : FRONT : 0 1 5 4
/// +Z : VT_NCI_Z_POS : TOP : 4 5 6 7
/// -Z : VT_NCI_Z_NEG : BOTTOM : 3 2 1 0
///
/// Corners:
/// 0 : VT_NCI_CORNER_XN_YN_ZN
/// 1 : VT_NCI_CORNER_XP_YN_ZN
/// 2 : VT_NCI_CORNER_XP_YP_ZN
/// 3 : VT_NCI_CORNER_XN_YP_ZN
/// 4 : VT_NCI_CORNER_XN_YN_ZP
/// 5 : VT_NCI_CORNER_XP_YN_ZP
/// 6 : VT_NCI_CORNER_XP_YP_ZP
/// 7 : VT_NCI_CORNER_XN_YP_ZP
///
/// Edges:
/// 01: VT_NCI_EDGE_YN_ZN
/// 12: VT_NCI_EDGE_XP_ZN
/// 23: VT_NCI_EDGE_YP_ZN
/// 03: VT_NCI_EDGE_XN_ZN
/// 45: VT_NCI_EDGE_YN_ZP
/// 56: VT_NCI_EDGE_XP_ZP
/// 67: VT_NCI_EDGE_YP_ZP
/// 47: VT_NCI_EDGE_XN_ZP
/// 04: VT_NCI_EDGE_XN_YN
/// 15: VT_NCI_EDGE_XP_YN
/// 26: VT_NCI_EDGE_XP_YP
/// 37: VT_NCI_EDGE_XN_YP
//--------------------------------------------------------------------------------------------------
void OverlayNavigationCube::createCubeGeos()
{
Vec3f cp[8];
navCubeCornerPoints(cp);
m_cubeGeos.clear();
createCubeFaceGeos(NCF_Y_NEG, cp[0], cp[1], cp[5], cp[4]);//, m_yNegAxisName, m_yFaceColor, m_textureNegYAxis.p()); // Front
createCubeFaceGeos(NCF_Y_POS, cp[2], cp[3], cp[7], cp[6]);//, m_yPosAxisName, m_yFaceColor, m_texturePosYAxis.p()); // Back
createCubeFaceGeos(NCF_Z_POS, cp[4], cp[5], cp[6], cp[7]);//, m_zPosAxisName, m_zFaceColor, m_texturePosZAxis.p()); // Top
createCubeFaceGeos(NCF_Z_NEG, cp[3], cp[2], cp[1], cp[0]);//, m_zNegAxisName, m_zFaceColor, m_textureNegZAxis.p()); // Bottom
createCubeFaceGeos(NCF_X_NEG, cp[3], cp[0], cp[4], cp[7]);//, m_xNegAxisName, m_xFaceColor, m_textureNegXAxis.p()); // left
createCubeFaceGeos(NCF_X_POS, cp[1], cp[2], cp[6], cp[5]);//, m_xPosAxisName, m_xFaceColor, m_texturePosXAxis.p()); // Right
}
//--------------------------------------------------------------------------------------------------
/// Face (with local indices):
/// 4 3
/// |z |---|----------|---|
/// | / y |TL | TOP |TR |
/// | / |---|----------|---|
/// *---x | | | |
/// | L | CENTER | R |
/// | | | |
/// |---|----------|---|
/// |BL | BOTTOM |BR |
/// |---|----------|---|
/// 1 2
//--------------------------------------------------------------------------------------------------
void OverlayNavigationCube::createCubeFaceGeos(NavCubeFace face, Vec3f p1, Vec3f p2, Vec3f p3, Vec3f p4)//, const String& name, const Color3f& baseColor, TextureImage* texture)
{
// Get the orientation vectors for the face
// Vec3f vNormal, vUp, vRight;
// faceOrientation(face, &vNormal, &vUp, &vRight);
float fCornerFactor = 0.175f;
Vec3f p12 = p1 + (p2 - p1)*fCornerFactor;
Vec3f p14 = p1 + (p4 - p1)*fCornerFactor;
Vec3f pi1 = p1 + (p12 - p1) + (p14 - p1);
Vec3f p21 = p2 + (p1 - p2)*fCornerFactor;
Vec3f p23 = p2 + (p3 - p2)*fCornerFactor;
Vec3f pi2 = p2 + (p21 - p2) + (p23 - p2);
Vec3f p32 = p3 + (p2 - p3)*fCornerFactor;
Vec3f p34 = p3 + (p4 - p3)*fCornerFactor;
Vec3f pi3 = p3 + (p32 - p3) + (p34 - p3);
Vec3f p41 = p4 + (p1 - p4)*fCornerFactor;
Vec3f p43 = p4 + (p3 - p4)*fCornerFactor;
Vec3f pi4 = p4 + (p41 - p4) + (p43 - p4);
// Bottom left
m_cubeItemType.push_back(navCubeItem(face, NCFI_BOTTOM_LEFT));
m_cubeGeos.push_back(createQuadGeo(p1, p12, pi1, p14).p());
// Bottom right
m_cubeItemType.push_back(navCubeItem(face, NCFI_BOTTOM_RIGHT));
m_cubeGeos.push_back(createQuadGeo(p2, p23, pi2, p21).p());
// Top right
m_cubeItemType.push_back(navCubeItem(face, NCFI_TOP_RIGHT));
m_cubeGeos.push_back(createQuadGeo(p3, p34, pi3, p32).p());
// Top left
m_cubeItemType.push_back(navCubeItem(face, NCFI_TOP_LEFT));
m_cubeGeos.push_back(createQuadGeo(p4, p41, pi4, p43).p());
// Bottom
m_cubeItemType.push_back(navCubeItem(face, NCFI_BOTTOM));
m_cubeGeos.push_back(createQuadGeo(p12, p21, pi2, pi1).p());
// Top
m_cubeItemType.push_back(navCubeItem(face, NCFI_TOP));
m_cubeGeos.push_back(createQuadGeo(p34, p43, pi4, pi3).p());
// Right
m_cubeItemType.push_back(navCubeItem(face, NCFI_RIGHT));
m_cubeGeos.push_back(createQuadGeo(p23, p32, pi3, pi2).p());
// Left
m_cubeItemType.push_back(navCubeItem(face, NCFI_LEFT));
m_cubeGeos.push_back(createQuadGeo(p41, p14, pi1, pi4).p());
// Inner part
m_cubeItemType.push_back(navCubeItem(face, NCFI_CENTER));
m_cubeGeos.push_back(createQuadGeo(pi1, pi2, pi3, pi4).p());
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
ref<DrawableGeo> OverlayNavigationCube::createQuadGeo(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3, const Vec3f& v4)
{
ref<DrawableGeo> geo = new DrawableGeo;
ref<Vec3fArray> vertexArray = new Vec3fArray(4);
vertexArray->set(0, v1);
vertexArray->set(1, v2);
vertexArray->set(2, v3);
vertexArray->set(3, v4);
geo->setVertexArray(vertexArray.p());
ref<cvf::UShortArray> indices = new cvf::UShortArray(6);
indices->set(0, 0);
indices->set(1, 1);
indices->set(2, 2);
indices->set(3, 0);
indices->set(4, 2);
indices->set(5, 3);
ref<cvf::PrimitiveSetIndexedUShort> primSet = new cvf::PrimitiveSetIndexedUShort(cvf::PT_TRIANGLES);
primSet->setIndices(indices.p());
geo->addPrimitiveSet(primSet.p());
return geo;
}
//--------------------------------------------------------------------------------------------------
/// 7---------6
/// /| /| |z
/// / | / | | / y
/// 4---------5 | | /
/// | 3------|--2 *---x
/// | / | /
/// |/ |/
/// 0---------1
//--------------------------------------------------------------------------------------------------
void OverlayNavigationCube::navCubeCornerPoints(Vec3f points[8])
{
float fBoxLength = 0.65f;
Vec3f min(-fBoxLength/2.0f, -fBoxLength/2.0f, -fBoxLength/2.0f);
Vec3f max(fBoxLength/2.0f, fBoxLength/2.0f, fBoxLength/2.0f);
points[0].set(min.x(), min.y(), min.z());
points[1].set(max.x(), min.y(), min.z());
points[2].set(max.x(), max.y(), min.z());
points[3].set(min.x(), max.y(), min.z());
points[4].set(min.x(), min.y(), max.z());
points[5].set(max.x(), min.y(), max.z());
points[6].set(max.x(), max.y(), max.z());
points[7].set(min.x(), max.y(), max.z());
}
/*************************************************************************************************
*//**
* Convert face + faceItem to VTNavCubeItem
*
*************************************************************************************************/
OverlayNavigationCube::NavCubeItem OverlayNavigationCube::navCubeItem(NavCubeFace face, NavCubeFaceItem faceItem) const
{
NavCubeItem item = NCI_NONE;
switch(face)
{
case NCF_X_POS:
{
switch(faceItem)
{
case NCFI_CENTER: item = NCI_FACE_X_POS; break;
case NCFI_TOP: item = NCI_EDGE_XP_ZP; break;
case NCFI_BOTTOM: item = NCI_EDGE_XP_ZN; break;
case NCFI_LEFT: item = NCI_EDGE_XP_YN; break;
case NCFI_RIGHT: item = NCI_EDGE_XP_YP; break;
case NCFI_TOP_LEFT: item = NCI_CORNER_XP_YN_ZP; break;
case NCFI_TOP_RIGHT: item = NCI_CORNER_XP_YP_ZP; break;
case NCFI_BOTTOM_LEFT: item = NCI_CORNER_XP_YN_ZN; break;
case NCFI_BOTTOM_RIGHT: item = NCI_CORNER_XP_YP_ZN; break;
case NCFI_NONE: item = NCI_NONE; break;
}
break;
}
case NCF_X_NEG:
{
switch(faceItem)
{
case NCFI_CENTER: item = NCI_FACE_X_NEG; break;
case NCFI_TOP: item = NCI_EDGE_XN_ZP; break;
case NCFI_BOTTOM: item = NCI_EDGE_XN_ZN; break;
case NCFI_LEFT: item = NCI_EDGE_XN_YP; break;
case NCFI_RIGHT: item = NCI_EDGE_XN_YN; break;
case NCFI_TOP_LEFT: item = NCI_CORNER_XN_YP_ZP; break;
case NCFI_TOP_RIGHT: item = NCI_CORNER_XN_YN_ZP; break;
case NCFI_BOTTOM_LEFT: item = NCI_CORNER_XN_YP_ZN; break;
case NCFI_BOTTOM_RIGHT: item = NCI_CORNER_XN_YN_ZN; break;
case NCFI_NONE: item = NCI_NONE; break;
}
break;
}
case NCF_Y_POS:
{
switch(faceItem)
{
case NCFI_CENTER: item = NCI_FACE_Y_POS; break;
case NCFI_TOP: item = NCI_EDGE_YP_ZP; break;
case NCFI_BOTTOM: item = NCI_EDGE_YP_ZN; break;
case NCFI_LEFT: item = NCI_EDGE_XP_YP; break;
case NCFI_RIGHT: item = NCI_EDGE_XN_YP; break;
case NCFI_TOP_LEFT: item = NCI_CORNER_XP_YP_ZP; break;
case NCFI_TOP_RIGHT: item = NCI_CORNER_XN_YP_ZP; break;
case NCFI_BOTTOM_LEFT: item = NCI_CORNER_XP_YP_ZN; break;
case NCFI_BOTTOM_RIGHT: item = NCI_CORNER_XN_YP_ZN; break;
case NCFI_NONE: item = NCI_NONE; break;
}
break;
}
case NCF_Y_NEG:
{
switch(faceItem)
{
case NCFI_CENTER: item = NCI_FACE_Y_NEG; break;
case NCFI_TOP: item = NCI_EDGE_YN_ZP; break;
case NCFI_BOTTOM: item = NCI_EDGE_YN_ZN; break;
case NCFI_LEFT: item = NCI_EDGE_XN_YN; break;
case NCFI_RIGHT: item = NCI_EDGE_XP_YN; break;
case NCFI_TOP_LEFT: item = NCI_CORNER_XN_YN_ZP; break;
case NCFI_TOP_RIGHT: item = NCI_CORNER_XP_YN_ZP; break;
case NCFI_BOTTOM_LEFT: item = NCI_CORNER_XN_YN_ZN; break;
case NCFI_BOTTOM_RIGHT: item = NCI_CORNER_XP_YN_ZN; break;
case NCFI_NONE: item = NCI_NONE; break;
}
break;
}
case NCF_Z_POS:
{
switch(faceItem)
{
case NCFI_CENTER: item = NCI_FACE_Z_POS; break;
case NCFI_TOP: item = NCI_EDGE_YP_ZP; break;
case NCFI_BOTTOM: item = NCI_EDGE_YN_ZP; break;
case NCFI_LEFT: item = NCI_EDGE_XN_ZP; break;
case NCFI_RIGHT: item = NCI_EDGE_XP_ZP; break;
case NCFI_TOP_LEFT: item = NCI_CORNER_XN_YP_ZP; break;
case NCFI_TOP_RIGHT: item = NCI_CORNER_XP_YP_ZP; break;
case NCFI_BOTTOM_LEFT: item = NCI_CORNER_XN_YN_ZP; break;
case NCFI_BOTTOM_RIGHT: item = NCI_CORNER_XP_YN_ZP; break;
case NCFI_NONE: item = NCI_NONE; break;
}
break;
}
case NCF_Z_NEG:
{
switch(faceItem)
{
case NCFI_CENTER: item = NCI_FACE_Z_NEG; break;
case NCFI_TOP: item = NCI_EDGE_YN_ZN; break;
case NCFI_BOTTOM: item = NCI_EDGE_YP_ZN; break;
case NCFI_LEFT: item = NCI_EDGE_XN_ZN; break;
case NCFI_RIGHT: item = NCI_EDGE_XP_ZN; break;
case NCFI_TOP_LEFT: item = NCI_CORNER_XN_YN_ZN; break;
case NCFI_TOP_RIGHT: item = NCI_CORNER_XP_YN_ZN; break;
case NCFI_BOTTOM_LEFT: item = NCI_CORNER_XN_YP_ZN; break;
case NCFI_BOTTOM_RIGHT: item = NCI_CORNER_XP_YP_ZN; break;
case NCFI_NONE: item = NCI_NONE; break;
}
break;
}
case NCF_NONE:
{
CVF_FAIL_MSG("Illegal nav cube face specified");
break;
}
}
return item;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayNavigationCube::faceOrientation(NavCubeFace face, Vec3f* normal, Vec3f* upVector, Vec3f* rightVector) const
{
CVF_ASSERT(normal && upVector && rightVector);
switch (face)
{
case NCF_X_POS: *normal = Vec3f::X_AXIS; break;
case NCF_X_NEG: *normal = -Vec3f::X_AXIS; break;
case NCF_Y_POS: *normal = Vec3f::Y_AXIS; break;
case NCF_Y_NEG: *normal = -Vec3f::Y_AXIS; break;
case NCF_Z_POS: *normal = Vec3f::Z_AXIS; break;
case NCF_Z_NEG: *normal = -Vec3f::Z_AXIS; break;
case NCF_NONE: CVF_FAIL_MSG("Illegal nav cube face"); break;
}
if ((*normal)*m_upVector == 0.0)
{
if (*normal == m_upVector) *upVector = -m_frontVector;
else *upVector = m_frontVector;
}
else
{
*upVector = m_upVector;
}
*rightVector = *upVector^*normal;
normal->normalize();
upVector->normalize();
rightVector->normalize();
}
} // namespace cvf

View File

@ -0,0 +1,187 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#pragma once
#include "cvfOverlayItem.h"
#include "cvfMatrix4.h"
#include "cvfColor3.h"
#include "cvfString.h"
#include "cvfBoundingBox.h"
#include "cvfCollection.h"
namespace cvf {
class Camera;
class DrawableGeo;
class DrawableVectors;
class Font;
class ShaderProgram;
class MatrixState;
class TextureImage;
//==================================================================================================
//
// Overlay axis cross
//
//==================================================================================================
class OverlayNavigationCube: public OverlayItem
{
public:
enum NavCubeFace {
NCF_NONE,
NCF_X_POS,
NCF_X_NEG,
NCF_Y_POS,
NCF_Y_NEG,
NCF_Z_POS,
NCF_Z_NEG
};
// Note that the order of the items starting at the VT_NCFI_BOTTOM_LEFT is important (in a CCW order)
enum NavCubeFaceItem {
NCFI_NONE,
NCFI_CENTER,
NCFI_BOTTOM_LEFT,
NCFI_BOTTOM,
NCFI_BOTTOM_RIGHT,
NCFI_RIGHT,
NCFI_TOP_RIGHT,
NCFI_TOP,
NCFI_TOP_LEFT,
NCFI_LEFT
};
enum NavCubeItem
{
NCI_NONE,
NCI_CORNER_XN_YN_ZN,
NCI_CORNER_XP_YN_ZN,
NCI_CORNER_XP_YP_ZN,
NCI_CORNER_XN_YP_ZN,
NCI_CORNER_XN_YN_ZP,
NCI_CORNER_XP_YN_ZP,
NCI_CORNER_XP_YP_ZP,
NCI_CORNER_XN_YP_ZP,
NCI_EDGE_YN_ZN,
NCI_EDGE_XP_ZN,
NCI_EDGE_YP_ZN,
NCI_EDGE_XN_ZN,
NCI_EDGE_YN_ZP,
NCI_EDGE_XP_ZP,
NCI_EDGE_YP_ZP,
NCI_EDGE_XN_ZP,
NCI_EDGE_XN_YN,
NCI_EDGE_XP_YN,
NCI_EDGE_XP_YP,
NCI_EDGE_XN_YP,
NCI_FACE_X_POS,
NCI_FACE_X_NEG,
NCI_FACE_Y_POS,
NCI_FACE_Y_NEG,
NCI_FACE_Z_POS,
NCI_FACE_Z_NEG,
NCI_ARROW_LEFT,
NCI_ARROW_RIGHT,
NCI_ARROW_TOP,
NCI_ARROW_BOTTOM,
NCI_HOME,
NCI_ROTATE_CW,
NCI_ROTATE_CCW
};
public:
OverlayNavigationCube(Camera* camera, Font* font);
~OverlayNavigationCube();
virtual Vec2ui sizeHint();
virtual Vec2ui maximumSize();
virtual Vec2ui minimumSize();
virtual void render(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size);
virtual void renderSoftware(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size);
void setSize(const Vec2ui& size);
void updateHighlight(int winCoordX, int winCoordY);
void processSelection(int winCoordX, int winCoordY, const BoundingBox& boundingBox, Vec3d* eye, Vec3d* viewDirection);
void setAxisLabels(const String& xLabel, const String& yLabel, const String& zlabel);
void setAxisLabelsColor(const Color3f& color);
private:
void render(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size, bool software, const Mat4d& viewMatrix);
void createAxisGeometry(bool software);
void renderAxis(OpenGLContext* oglContext, const MatrixState& matrixState);
void renderAxisImmediateMode(OpenGLContext* oglContext, const MatrixState& matrixState);
void renderAxisLabels(OpenGLContext* oglContext, bool software, const MatrixState& matrixState);
void renderCubeGeos(OpenGLContext* oglContext, bool software, const MatrixState& matrixState);
void createCubeGeos();
void createCubeFaceGeos(NavCubeFace face, Vec3f p1, Vec3f p2, Vec3f p3, Vec3f p4);//, const String& name, const Color3f& baseColor, TextureImage* texture);
void navCubeCornerPoints(Vec3f points[8]);
ref<DrawableGeo> createQuadGeo(const Vec3f& v1, const Vec3f& v2, const Vec3f& v3, const Vec3f& v4);
NavCubeItem navCubeItem(NavCubeFace face, NavCubeFaceItem item) const;
void faceOrientation(NavCubeFace face, Vec3f* normal, Vec3f* upVector, Vec3f* rightVector) const;
private:
ref<Camera> m_camera; // This camera's view matrix will be used to orient the axis cross
String m_xLabel; // Label to display on x axis, default 'x'
String m_yLabel;
String m_zLabel;
Color3f m_textColor; // Text color
ref<Font> m_font;
Vec2ui m_size; // Pixel size of the axis area
Collection<DrawableGeo> m_cubeGeos;
std::vector<NavCubeItem> m_cubeItemType;
ref<ShaderProgram> m_cubeGeoShader;
ref<DrawableVectors> m_axis;
NavCubeItem m_hightlightItem; ///< The currently highlighted cube item (face, corner, edge, buttons)
Vec3f m_upVector; ///< Specify the up vector, which is used for the orientation of the text and textures on the faces
Vec3f m_frontVector; ///< Specify the front vector, which is used for the orientation of the top and bottom faces
String m_xPosAxisName; ///< The name of the X_POS face
String m_xNegAxisName; ///< The name of the X_NEG face
String m_yPosAxisName; ///< The name of the Y_POS face
String m_yNegAxisName; ///< The name of the Y_NEG face
String m_zPosAxisName; ///< The name of the Z_POS face
String m_zNegAxisName; ///< The name of the Z_NEG face
ref<TextureImage> m_texturePosXAxis; ///< The texture to draw on the X_POS face. If NULL, the specified text will be drawn.
ref<TextureImage> m_textureNegXAxis; ///< The texture to draw on the X_NEG face. If NULL, the specified text will be drawn.
ref<TextureImage> m_texturePosYAxis; ///< The texture to draw on the Y_POS face. If NULL, the specified text will be drawn.
ref<TextureImage> m_textureNegYAxis; ///< The texture to draw on the Y_NEG face. If NULL, the specified text will be drawn.
ref<TextureImage> m_texturePosZAxis; ///< The texture to draw on the Z_POS face. If NULL, the specified text will be drawn.
ref<TextureImage> m_textureNegZAxis; ///< The texture to draw on the Z_NEG face. If NULL, the specified text will be drawn.
Color3f m_xFaceColor; ///< The color of the X_POS and X_NEG faces
Color3f m_yFaceColor; ///< The color of the Y_POS and Y_NEG faces
Color3f m_zFaceColor; ///< The color of the Z_POS and Z_NEG faces
};
}

View File

@ -0,0 +1,730 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfOverlayScalarMapperLegend.h"
#include "cvfOpenGL.h"
#include "cvfOpenGLResourceManager.h"
#include "cvfGeometryBuilderDrawableGeo.h"
#include "cvfGeometryUtils.h"
#include "cvfViewport.h"
#include "cvfCamera.h"
#include "cvfTextDrawer.h"
#include "cvfFont.h"
#include "cvfShaderProgram.h"
#include "cvfShaderProgramGenerator.h"
#include "cvfShaderSourceProvider.h"
#include "cvfShaderSourceRepository.h"
#include "cvfUniform.h"
#include "cvfMatrixState.h"
#include "cvfBufferObjectManaged.h"
#include "cvfGlyph.h"
#include "cvfRenderStateDepth.h"
#include "cvfRenderStateLine.h"
#ifndef CVF_OPENGL_ES
#include "cvfRenderState_FF.h"
#endif
#include "cvfScalarMapper.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::OverlayColorLegend
/// \ingroup Render
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
/// Constructor
//--------------------------------------------------------------------------------------------------
OverlayScalarMapperLegend::OverlayScalarMapperLegend(Font* font)
: m_sizeHint(200, 200),
m_color(Color3::BLACK),
m_lineColor(Color3::BLACK),
m_lineWidth(1),
m_font(font)
{
CVF_ASSERT(font);
CVF_ASSERT(!font->isEmpty());
m_tickValues.reserve(3);
m_tickValues.add(0.0);
m_tickValues.add(0.5);
m_tickValues.add(1.0);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
OverlayScalarMapperLegend::~OverlayScalarMapperLegend()
{
// Empty destructor to avoid errors with undefined types when cvf::ref's destructor gets called
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec2ui OverlayScalarMapperLegend::sizeHint()
{
return m_sizeHint;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec2ui OverlayScalarMapperLegend::maximumSize()
{
return m_sizeHint;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::Vec2ui OverlayScalarMapperLegend::minimumSize()
{
return Vec2ui(100,100);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayScalarMapperLegend::setScalarMapper(const ScalarMapper* scalarMapper)
{
m_scalarMapper = scalarMapper;
if (m_scalarMapper.notNull())
{
std::vector<double> levelValues;
m_scalarMapper->majorTickValues(&levelValues);
m_tickValues.assign(levelValues);
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayScalarMapperLegend::setSizeHint(const Vec2ui& size)
{
m_sizeHint = size;
}
//--------------------------------------------------------------------------------------------------
/// Set color of the text and lines to be rendered
//--------------------------------------------------------------------------------------------------
void OverlayScalarMapperLegend::setColor(const Color3f& color)
{
m_color = color;
}
//--------------------------------------------------------------------------------------------------
/// Returns the color of the text and lines
//--------------------------------------------------------------------------------------------------
const Color3f& OverlayScalarMapperLegend::color() const
{
return m_color;
}
//--------------------------------------------------------------------------------------------------
/// Set the title (text that will be rendered above the legend)
///
/// The legend supports multi-line titles. Separate each line with a '\n' character
//--------------------------------------------------------------------------------------------------
void OverlayScalarMapperLegend::setTitle(const String& title)
{
// Title
if (title.isEmpty())
{
m_titleStrings.clear();
}
else
{
m_titleStrings = title.split("\n");
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
String OverlayScalarMapperLegend::title() const
{
String title;
for (size_t i = 0; i < m_titleStrings.size(); ++i)
{
title += m_titleStrings[i];
if (i != m_titleStrings.size() - 1)
{
title += "\n";
}
}
return title;
}
//--------------------------------------------------------------------------------------------------
/// Hardware rendering using shader programs
//--------------------------------------------------------------------------------------------------
void OverlayScalarMapperLegend::render(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size)
{
render(oglContext, position, size, false);
}
//--------------------------------------------------------------------------------------------------
/// Software rendering using software
//--------------------------------------------------------------------------------------------------
void OverlayScalarMapperLegend::renderSoftware(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size)
{
render(oglContext, position, size, true);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool OverlayScalarMapperLegend::pick(uint oglXCoord, uint oglYCoord, const Vec2ui& position, const Vec2ui& size)
{
Rectui oglRect(position, size.x(), size.y());
OverlayColorLegendLayoutInfo layoutInViewPortCoords(oglRect.min(), Vec2ui(oglRect.width(), oglRect.height()));
layoutInfo(&layoutInViewPortCoords);
Vec2ui legendBarOrigin = oglRect.min();
legendBarOrigin.x() += static_cast<uint>(layoutInViewPortCoords.legendRect.min().x());
legendBarOrigin.y() += static_cast<uint>(layoutInViewPortCoords.legendRect.min().y());
Rectui legendBarRect = Rectui(legendBarOrigin, static_cast<uint>(layoutInViewPortCoords.legendRect.width()), static_cast<uint>(layoutInViewPortCoords.legendRect.height()));
if ((oglXCoord > legendBarRect.min().x()) && (oglXCoord < legendBarRect.max().x()) &&
(oglYCoord > legendBarRect.min().y()) && (oglYCoord < legendBarRect.max().y()))
{
return true;
}
return false;
}
//--------------------------------------------------------------------------------------------------
/// Set up camera/viewport and render
//--------------------------------------------------------------------------------------------------
void OverlayScalarMapperLegend::render(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size, bool software)
{
if (size.x() <= 0 || size.y() <= 0)
{
return;
}
Camera camera;
camera.setViewport(position.x(), position.y(), size.x(), size.y());
camera.setProjectionAsPixelExact2D();
camera.setViewMatrix(Mat4d::IDENTITY);
camera.applyOpenGL();
camera.viewport()->applyOpenGL(oglContext, Viewport::CLEAR_DEPTH);
// Get layout information
// Todo: Cache this between renderings. Update only when needed.
OverlayColorLegendLayoutInfo layout(position, size);
layoutInfo(&layout);
// Set up text drawer
TextDrawer textDrawer(m_font.p());
setupTextDrawer(&textDrawer, &layout);
// Do the actual rendering
if (software)
{
renderLegendImmediateMode(oglContext, &layout);
textDrawer.renderSoftware(oglContext, camera);
}
else
{
const MatrixState matrixState(camera);
renderLegend(oglContext, &layout, matrixState);
textDrawer.render(oglContext, camera);
}
CVF_CHECK_OGL(oglContext);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayScalarMapperLegend::setupTextDrawer(TextDrawer* textDrawer, OverlayColorLegendLayoutInfo* layout)
{
CVF_ASSERT(layout);
textDrawer->setVerticalAlignment(TextDrawer::CENTER);
textDrawer->setTextColor(m_color);
m_visibleTickLabels.clear();
const float textX = layout->tickX + 5;
const float overlapTolerance = 1.2f * layout->charHeight;
float lastVisibleTextY = 0.0;
size_t numTicks = m_tickValues.size();
size_t it;
for (it = 0; it < numTicks; it++)
{
float textY = static_cast<float>(layout->legendRect.min().y() + layout->tickPixelPos->get(it));
// Always draw first and last tick label. For all others, skip drawing if text ends up
// on top of the previous label.
if (it != 0 && it != (numTicks - 1))
{
if (cvf::Math::abs(textY - lastVisibleTextY) < overlapTolerance)
{
m_visibleTickLabels.push_back(false);
continue;
}
// Make sure it does not overlap the last tick as well
float lastTickY = static_cast<float>(layout->legendRect.max().y() );
if (cvf::Math::abs(textY - lastTickY) < overlapTolerance)
{
m_visibleTickLabels.push_back(false);
continue;
}
}
double tickValue = m_tickValues[it];
String valueString = String::number(tickValue);
Vec2f pos(textX, textY);
textDrawer->addText(valueString, pos);
lastVisibleTextY = textY;
m_visibleTickLabels.push_back(true);
}
float titleY = static_cast<float>(layout->size.y()) - layout->margins.y() - layout->charHeight/2.0f;
for (it = 0; it < m_titleStrings.size(); it++)
{
Vec2f pos(layout->margins.x(), titleY);
textDrawer->addText(m_titleStrings[it], pos);
titleY -= layout->lineSpacing;
}
}
//--------------------------------------------------------------------------------------------------
/// Draw the legend using shader programs
//--------------------------------------------------------------------------------------------------
void OverlayScalarMapperLegend::renderLegend(OpenGLContext* oglContext, OverlayColorLegendLayoutInfo* layout, const MatrixState& matrixState)
{
CVF_CALLSITE_OPENGL(oglContext);
CVF_TIGHT_ASSERT(layout);
CVF_TIGHT_ASSERT(layout->size.x() > 0);
CVF_TIGHT_ASSERT(layout->size.y() > 0);
RenderStateDepth depth(false);
depth.applyOpenGL(oglContext);
RenderStateLine line(static_cast<float>(m_lineWidth));
line.applyOpenGL(oglContext);
// All vertices. Initialized here to set Z to zero once and for all.
static float vertexArray[] =
{
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f
};
// Per vector convenience pointers
float* v0 = &vertexArray[0];
float* v1 = &vertexArray[3];
float* v2 = &vertexArray[6];
float* v3 = &vertexArray[9];
float* v4 = &vertexArray[12];
// Constant coordinates
v0[0] = v3[0] = layout->x0;
v1[0] = v4[0] = layout->x1;
// Connects
static const ushort trianglesConnects[] = { 0, 1, 4, 0, 4, 3 };
ref<ShaderProgram> shaderProgram = oglContext->resourceManager()->getLinkedUnlitColorShaderProgram(oglContext);
CVF_TIGHT_ASSERT(shaderProgram.notNull());
if (shaderProgram->useProgram(oglContext))
{
shaderProgram->clearUniformApplyTracking();
shaderProgram->applyFixedUniforms(oglContext, matrixState);
}
glBindBuffer(GL_ARRAY_BUFFER, 0);
glEnableVertexAttribArray(ShaderProgram::VERTEX);
glVertexAttribPointer(ShaderProgram::VERTEX, 3, GL_FLOAT, GL_FALSE, 0, vertexArray);
// Render color bar as one colored quad per pixel
int legendHeightPixelCount = static_cast<int>(layout->tickPixelPos->get(m_tickValues.size()-1) - layout->tickPixelPos->get(0) + 0.01);
if (m_scalarMapper.notNull())
{
int iPx;
for (iPx = 0; iPx < legendHeightPixelCount; iPx++)
{
const Color3ub& clr = m_scalarMapper->mapToColor(m_scalarMapper->domainValue((iPx+0.5)/legendHeightPixelCount));
float y0 = static_cast<float>(layout->legendRect.min().y() + iPx);
float y1 = static_cast<float>(layout->legendRect.min().y() + iPx + 1);
// Dynamic coordinates for rectangle
v0[1] = v1[1] = y0;
v3[1] = v4[1] = y1;
// Draw filled rectangle elements
{
UniformFloat uniformColor("u_color", Color4f(Color3f(clr)));
shaderProgram->applyUniform(oglContext, uniformColor);
#ifdef CVF_OPENGL_ES
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_SHORT, trianglesConnects);
#else
glDrawRangeElements(GL_TRIANGLES, 0, 4, 6, GL_UNSIGNED_SHORT, trianglesConnects);
#endif
}
}
}
// Render frame
// Dynamic coordinates for tickmarks-lines
bool isRenderingFrame = true;
if (isRenderingFrame)
{
v0[0] = v2[0] = layout->legendRect.min().x()-0.5f;
v1[0] = v3[0] = layout->legendRect.max().x()-0.5f;
v0[1] = v1[1] = layout->legendRect.min().y()-0.5f;
v2[1] = v3[1] = layout->legendRect.max().y()-0.5f;
static const ushort frameConnects[] = { 0, 1, 1, 3, 3, 2, 2, 0};
UniformFloat uniformColor("u_color", Color4f(m_lineColor));
shaderProgram->applyUniform(oglContext, uniformColor);
#ifdef CVF_OPENGL_ES
glDrawElements(GL_LINES, 8, GL_UNSIGNED_SHORT, frameConnects);
#else
glDrawRangeElements(GL_LINES, 0, 3, 8, GL_UNSIGNED_SHORT, frameConnects);
#endif
}
// Render tickmarks
bool isRenderingTicks = true;
if (isRenderingTicks)
{
// Constant coordinates
v0[0] = layout->x0;
v1[0] = layout->x1 - 0.5f*(layout->tickX - layout->x1) - 0.5f;
v2[0] = layout->x1;
v3[0] = layout->tickX - 0.5f*(layout->tickX - layout->x1) - 0.5f;
v4[0] = layout->tickX;
static const ushort tickLinesWithLabel[] = { 0, 4 };
static const ushort tickLinesWoLabel[] = { 2, 3 };
size_t ic;
for (ic = 0; ic < m_tickValues.size(); ic++)
{
float y0 = static_cast<float>(layout->legendRect.min().y() + layout->tickPixelPos->get(ic) - 0.5f);
// Dynamic coordinates for tickmarks-lines
v0[1] = v1[1] = v2[1] = v3[1] = v4[1] = y0;
UniformFloat uniformColor("u_color", Color4f(m_lineColor));
shaderProgram->applyUniform(oglContext, uniformColor);
const ushort * linesConnects;
if ( m_visibleTickLabels[ic])
{
linesConnects = tickLinesWithLabel;
}
else
{
linesConnects = tickLinesWoLabel;
}
#ifdef CVF_OPENGL_ES
glDrawElements(GL_LINES, 2, GL_UNSIGNED_SHORT, linesConnects);
#else
glDrawRangeElements(GL_LINES, 0, 4, 2, GL_UNSIGNED_SHORT, linesConnects);
#endif
}
}
glDisableVertexAttribArray(ShaderProgram::VERTEX);
CVF_TIGHT_ASSERT(shaderProgram.notNull());
shaderProgram->useNoProgram(oglContext);
// Reset render states
RenderStateDepth resetDepth;
resetDepth.applyOpenGL(oglContext);
RenderStateLine resetLine;
resetLine.applyOpenGL(oglContext);
CVF_CHECK_OGL(oglContext);
}
//--------------------------------------------------------------------------------------------------
/// Draw the legend using immediate mode OpenGL
//--------------------------------------------------------------------------------------------------
void OverlayScalarMapperLegend::renderLegendImmediateMode(OpenGLContext* oglContext, OverlayColorLegendLayoutInfo* layout)
{
#ifdef CVF_OPENGL_ES
CVF_UNUSED(layout);
CVF_FAIL_MSG("Not supported on OpenGL ES");
#else
CVF_TIGHT_ASSERT(layout);
CVF_TIGHT_ASSERT(layout->size.x() > 0);
CVF_TIGHT_ASSERT(layout->size.y() > 0);
RenderStateDepth depth(false);
depth.applyOpenGL(oglContext);
RenderStateLighting_FF lighting(false);
lighting.applyOpenGL(oglContext);
// All vertices. Initialized here to set Z to zero once and for all.
static float vertexArray[] =
{
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
0.0f, 0.0f, 0.0f,
};
// Per vector convenience pointers
float* v0 = &vertexArray[0];
float* v1 = &vertexArray[3];
float* v2 = &vertexArray[6];
float* v3 = &vertexArray[9];
float* v4 = &vertexArray[12];
// Constant coordinates
v0[0] = v3[0] = layout->x0;
v1[0] = v4[0] = layout->x1;
// Render color bar as one colored quad per pixel
int legendHeightPixelCount = static_cast<int>(layout->tickPixelPos->get(m_tickValues.size() - 1) - layout->tickPixelPos->get(0) + 0.01);
if (m_scalarMapper.notNull())
{
int iPx;
for (iPx = 0; iPx < legendHeightPixelCount; iPx++)
{
const Color3ub& clr = m_scalarMapper->mapToColor(m_scalarMapper->domainValue((iPx+0.5)/legendHeightPixelCount));
float y0 = static_cast<float>(layout->legendRect.min().y() + iPx);
float y1 = static_cast<float>(layout->legendRect.min().y() + iPx + 1);
// Dynamic coordinates for rectangle
v0[1] = v1[1] = y0;
v3[1] = v4[1] = y1;
// Draw filled rectangle elements
glColor3ubv(clr.ptr());
glBegin(GL_TRIANGLE_FAN);
glVertex3fv(v0);
glVertex3fv(v1);
glVertex3fv(v4);
glVertex3fv(v3);
glEnd();
}
}
// Render frame
// Dynamic coordinates for tickmarks-lines
bool isRenderingFrame = true;
if (isRenderingFrame)
{
v0[0] = v2[0] = layout->legendRect.min().x()-0.5f;
v1[0] = v3[0] = layout->legendRect.max().x()-0.5f;
v0[1] = v1[1] = layout->legendRect.min().y()-0.5f;
v2[1] = v3[1] = layout->legendRect.max().y()-0.5f;
glColor3fv(m_color.ptr());
glBegin(GL_LINES);
glVertex3fv(v0);
glVertex3fv(v1);
glVertex3fv(v1);
glVertex3fv(v3);
glVertex3fv(v3);
glVertex3fv(v2);
glVertex3fv(v2);
glVertex3fv(v0);
glEnd();
}
// Render tickmarks
bool isRenderingTicks = true;
if (isRenderingTicks)
{
// Constant coordinates
v0[0] = layout->x0;
v1[0] = layout->x1 - 0.5f*(layout->tickX - layout->x1) - 0.5f;
v2[0] = layout->x1;
v3[0] = layout->tickX - 0.5f*(layout->tickX - layout->x1) - 0.5f;
v4[0] = layout->tickX;
size_t ic;
for (ic = 0; ic < m_tickValues.size(); ic++)
{
float y0 = static_cast<float>(layout->legendRect.min().y() + layout->tickPixelPos->get(ic) - 0.5f);
// Dynamic coordinates for tickmarks-lines
v0[1] = v1[1] = v2[1] = v3[1] = v4[1] = y0;
glColor3fv(m_color.ptr());
glBegin(GL_LINES);
if ( m_visibleTickLabels[ic])
{
glVertex3fv(v0);
glVertex3fv(v4);
}
else
{
glVertex3fv(v2);
glVertex3fv(v3);
}
glEnd();
}
}
// Reset render states
RenderStateLighting_FF resetLighting;
resetLighting.applyOpenGL(oglContext);
RenderStateDepth resetDepth;
resetDepth.applyOpenGL(oglContext);
CVF_CHECK_OGL(oglContext);
#endif // CVF_OPENGL_ES
}
//--------------------------------------------------------------------------------------------------
/// Get layout information
//--------------------------------------------------------------------------------------------------
void OverlayScalarMapperLegend::layoutInfo(OverlayColorLegendLayoutInfo* layout)
{
CVF_TIGHT_ASSERT(layout);
ref<Glyph> glyph = m_font->getGlyph(L'A');
layout->charHeight = static_cast<float>(glyph->height());
layout->lineSpacing = layout->charHeight*1.5f;
layout->margins = Vec2f(4.0f, 4.0f);
float legendWidth = 25.0f;
float legendHeight = static_cast<float>(layout->size.y()) - 2*layout->margins.y() - static_cast<float>(m_titleStrings.size())*layout->lineSpacing - layout->lineSpacing;
layout->legendRect = Rectf(layout->margins.x(), layout->margins.y() + layout->charHeight/2.0f, legendWidth, legendHeight);
if (layout->legendRect.width() < 1 || layout->legendRect.height() < 1)
{
return;
}
layout->x0 = layout->margins.x();
layout->x1 = layout->margins.x() + layout->legendRect.width();
layout->tickX = layout->x1 + 5;
// Build array containing the pixel positions of all the ticks
size_t numTicks = m_tickValues.size();
layout->tickPixelPos = new DoubleArray(numTicks);
size_t i;
for (i = 0; i < numTicks; i++)
{
double t;
if (m_scalarMapper.isNull()) t = 0;
else t = m_scalarMapper->normalizedValue(m_tickValues[i]);
t = Math::clamp(t, 0.0, 1.1);
layout->tickPixelPos->set(i, t*layout->legendRect.height());
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayScalarMapperLegend::setLineColor(const Color3f& lineColor)
{
m_lineColor = lineColor;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const Color3f& OverlayScalarMapperLegend::lineColor() const
{
return m_lineColor;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void OverlayScalarMapperLegend::setLineWidth(int lineWidth)
{
m_lineWidth = lineWidth;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int OverlayScalarMapperLegend::lineWidth() const
{
return m_lineWidth;
}
} // namespace cvf

View File

@ -0,0 +1,123 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#pragma once
#include "cvfOverlayItem.h"
#include "cvfArray.h"
#include "cvfCamera.h"
#include "cvfString.h"
#include "cvfRect.h"
namespace cvf {
class Font;
class ShaderProgram;
class MatrixState;
class TextDrawer;
class ScalarMapper;
//==================================================================================================
//
// Overlay color legend
//
//==================================================================================================
class OverlayScalarMapperLegend : public OverlayItem
{
public:
OverlayScalarMapperLegend(Font* font);
virtual ~OverlayScalarMapperLegend();
virtual Vec2ui sizeHint();
virtual Vec2ui maximumSize();
virtual Vec2ui minimumSize();
void setScalarMapper(const ScalarMapper* scalarMapper);
virtual void render(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size);
virtual void renderSoftware(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size);
virtual bool pick(uint oglXCoord, uint oglYCoord, const Vec2ui& position, const Vec2ui& size);
void setSizeHint(const Vec2ui& size);
void setColor(const Color3f& color);
const Color3f& color() const;
void setLineColor(const Color3f& lineColor);
const Color3f& lineColor() const;
void setLineWidth(int lineWidth);
int lineWidth() const;
void setTitle(const String& title);
String title() const;
protected:
//==================================================================================================
//
// Helper for storing layout info
//
//==================================================================================================
struct OverlayColorLegendLayoutInfo
{
OverlayColorLegendLayoutInfo(const Vec2ui& pos, const Vec2ui& setSize)
{
position = pos;
size = setSize;
}
float charHeight;
float lineSpacing;
Vec2f margins;
float tickX;
float x0, x1;
Rectf legendRect;
ref<DoubleArray> tickPixelPos;
Vec2ui position;
Vec2ui size;
};
void render(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size, bool software);
virtual void renderLegend(OpenGLContext* oglContext, OverlayColorLegendLayoutInfo* layout, const MatrixState& matrixState);
virtual void renderLegendImmediateMode(OpenGLContext* oglContext, OverlayColorLegendLayoutInfo* layout);
virtual void setupTextDrawer(TextDrawer* textDrawer, OverlayColorLegendLayoutInfo* layout);
void layoutInfo(OverlayColorLegendLayoutInfo* layout);
protected:
DoubleArray m_tickValues; // Ticks between each level + top and bottom of legend (n+1 entries)
std::vector<bool> m_visibleTickLabels; // Skip tick labels ending up on top of previous visible label
Vec2ui m_sizeHint; // Pixel size of the color legend area
Color3f m_color;
Color3f m_lineColor;
int m_lineWidth;
std::vector<String> m_titleStrings;
ref<Font> m_font;
cref<ScalarMapper> m_scalarMapper;
};
}

View File

@ -22,12 +22,15 @@
#include "cvfDrawableText.h"
#include "cvfMatrixState.h"
#include "cvfCamera.h"
#include "cvfRenderState.h"
#include "cvfShaderProgram.h"
#include "cvfOpenGL.h"
#include "cvfViewport.h"
#include "cvfOpenGLResourceManager.h"
#include "cvfUniform.h"
#include "cvfRenderStateDepth.h"
#include "cvfFont.h"
#include "cvfGlyph.h"
#include "cvfRenderStateLine.h"
#ifndef CVF_OPENGL_ES
#include "cvfRenderState_FF.h"
@ -49,6 +52,7 @@ namespace cvf {
//--------------------------------------------------------------------------------------------------
OverlayTextBox::OverlayTextBox(Font* font)
: m_size(200, 50),
m_font(font),
m_drawBackground(true),
m_drawBorder(true),
m_textColor(Color3::WHITE),
@ -56,7 +60,7 @@ OverlayTextBox::OverlayTextBox(Font* font)
m_borderColor(0.6f, 0.6f, 1.0f)
{
m_textDrawer = new TextDrawer(font);
m_textDrawer->setVerticalAlignment(TextDrawer::CENTER);
m_textDrawer->setVerticalAlignment(TextDrawer::BASELINE);
m_textDrawer->setDrawBackground(false);
m_textDrawer->setDrawBorder(false);
}
@ -130,6 +134,9 @@ void OverlayTextBox::render(OpenGLContext* oglContext, const Vec2ui& position, c
textPos.x() = 4; // Allow for margin
}
Vec2ui textExtent = m_font->textExtent(m_text);
textPos.y() -= (static_cast<float>(textExtent.y())/2.0f);
// Set the text
m_textDrawer->removeAllTexts();
m_textDrawer->addText(m_text, textPos);
@ -161,7 +168,7 @@ void OverlayTextBox::renderBackgroundAndBorder(OpenGLContext* oglContext, const
projCam.setViewMatrix(Mat4d::IDENTITY);
// Turn off depth test
Depth depth(false, Depth::LESS, false);
RenderStateDepth depth(false, RenderStateDepth::LESS, false);
depth.applyOpenGL(oglContext);
ref<ShaderProgram> backgroundShader;
@ -177,11 +184,11 @@ void OverlayTextBox::renderBackgroundAndBorder(OpenGLContext* oglContext, const
}
#ifndef CVF_OPENGL_ES
Material_FF mat;
RenderStateMaterial_FF mat;
mat.enableColorMaterial(true);
mat.applyOpenGL(oglContext);
Lighting_FF light(false);
RenderStateLighting_FF light(false);
light.applyOpenGL(oglContext);
#endif
projCam.applyOpenGL();
@ -256,8 +263,14 @@ void OverlayTextBox::renderBackgroundAndBorder(OpenGLContext* oglContext, const
UniformFloat borderColor("u_color", Color4f(m_borderColor));
backgroundShader->applyUniform(oglContext, borderColor);
RenderStateLine line(static_cast<float>(3));
line.applyOpenGL(oglContext);
// Draw border
glDrawArrays(GL_LINE_LOOP, 0, 4);
RenderStateLine resetLine;
resetLine.applyOpenGL(oglContext);
}
}
}
@ -275,12 +288,35 @@ void OverlayTextBox::setText(const String& text)
//--------------------------------------------------------------------------------------------------
/// Set the size (in pixels) of the text box
//--------------------------------------------------------------------------------------------------
void OverlayTextBox::setSize( const Vec2ui& size )
void OverlayTextBox::setPixelSize( const Vec2ui& size )
{
m_size = size;
}
//--------------------------------------------------------------------------------------------------
/// Set the size of the text box to fit the current text.
///
/// The method will also add a bit of space for the border or background if enabled.
//--------------------------------------------------------------------------------------------------
void OverlayTextBox::setSizeToFitText()
{
cvf::Vec2ui textSize = m_font->textExtent(m_text);
// Add the size of an 'A' as the margin, same as used in the Text Drawer
ref<Glyph> glyph = m_font->getGlyph(L'A');
Vec2ui size = Vec2ui(textSize.x() + glyph->width(), textSize.y() + glyph->height());
if (m_drawBorder)
{
size.x() += 4;
size.y() += 4;
}
setPixelSize(size);
}
//--------------------------------------------------------------------------------------------------
/// Set the text color
//--------------------------------------------------------------------------------------------------

View File

@ -48,7 +48,9 @@ public:
virtual void renderSoftware(OpenGLContext* oglContext, const Vec2ui& position, const Vec2ui& size);
void setText(const String& text);
void setSize(const Vec2ui& size);
void setPixelSize(const Vec2ui& size);
void setSizeToFitText();
void setTextColor(const Color3f& color);
void setBackgroundColor(const Color3f& color);
void setBorderColor(const Color3f& color);
@ -71,6 +73,7 @@ private:
Vec2ui m_size;
String m_text;
ref<TextDrawer> m_textDrawer;
ref<Font> m_font;
bool m_drawBackground;
bool m_drawBorder;

View File

@ -49,6 +49,18 @@ PrimitiveSetIndexedUInt::PrimitiveSetIndexedUInt(PrimitiveType primitiveType)
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PrimitiveSetIndexedUInt::PrimitiveSetIndexedUInt(PrimitiveType primitiveType, UIntArray* indices)
: PrimitiveSet(primitiveType),
m_minIndex(0),
m_maxIndex(0)
{
setIndices(indices);
}
//--------------------------------------------------------------------------------------------------
/// Deletes OpenGL resources created by this primitive set
//--------------------------------------------------------------------------------------------------

View File

@ -35,6 +35,7 @@ class PrimitiveSetIndexedUInt : public PrimitiveSet
{
public:
PrimitiveSetIndexedUInt(PrimitiveType primitiveType);
PrimitiveSetIndexedUInt(PrimitiveType primitiveType, UIntArray* indices);
virtual ~PrimitiveSetIndexedUInt();
virtual void render(OpenGLContext* oglContext) const;

View File

@ -50,6 +50,18 @@ PrimitiveSetIndexedUShort::PrimitiveSetIndexedUShort(PrimitiveType primitiveType
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
PrimitiveSetIndexedUShort::PrimitiveSetIndexedUShort(PrimitiveType primitiveType, UShortArray* indices)
: PrimitiveSet(primitiveType),
m_minIndex(0),
m_maxIndex(0)
{
setIndices(indices);
}
//--------------------------------------------------------------------------------------------------
/// Deletes OpenGL resources created by this primitive set
//--------------------------------------------------------------------------------------------------

View File

@ -35,6 +35,7 @@ class PrimitiveSetIndexedUShort : public PrimitiveSet
{
public:
PrimitiveSetIndexedUShort(PrimitiveType primitiveType);
PrimitiveSetIndexedUShort(PrimitiveType primitiveType, UShortArray* indices);
virtual ~PrimitiveSetIndexedUShort();
virtual void render(OpenGLContext* oglContext) const;

File diff suppressed because it is too large Load Diff

View File

@ -20,16 +20,10 @@
#pragma once
#include "cvfObject.h"
#include "cvfOpenGLTypes.h"
#include "cvfColor4.h"
#include "cvfString.h"
namespace cvf {
class OpenGLContext;
class ShaderProgram;
class Sampler;
class Texture;
//==================================================================================================
@ -45,11 +39,13 @@ public:
BLENDING, // Must start at 0, used for indexing in RenderStateTracker
COLOR_MASK,
CULL_FACE,
FRONT_FACE,
DEPTH,
FRONT_FACE,
LINE,
POINT,
POLYGON_MODE,
POLYGON_OFFSET,
STENCIL,
TEXTURE_BINDINGS,
#ifndef CVF_OPENGL_ES
@ -78,348 +74,5 @@ private:
//==================================================================================================
//
// Controls OpenGL blending
//
//==================================================================================================
class Blending : public RenderState
{
public:
enum Function
{
ZERO,
ONE,
SRC_COLOR,
ONE_MINUS_SRC_COLOR,
DST_COLOR,
ONE_MINUS_DST_COLOR,
SRC_ALPHA,
ONE_MINUS_SRC_ALPHA,
DST_ALPHA,
ONE_MINUS_DST_ALPHA,
CONSTANT_COLOR,
ONE_MINUS_CONSTANT_COLOR,
CONSTANT_ALPHA,
ONE_MINUS_CONSTANT_ALPHA,
SRC_ALPHA_SATURATE
};
enum Equation
{
FUNC_ADD,
FUNC_SUBTRACT,
FUNC_REVERSE_SUBTRACT,
MIN, // Unsupported on OpenGL ES
MAX // Unsupported on OpenGL ES
};
public:
Blending();
void enableBlending(bool blend);
void setFunction(Function source, Function destination);
void setEquation(Equation equation);
void setFunctionSeparate(Function sourceRGB, Function destinationRGB, Function sourceAlpha, Function destinationAlpha);
void setEquationSeparate(Equation equationRGB, Equation equationAlpha);
void setBlendColor(Color4f blendColor);
void configureTransparencyBlending();
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
cvfGLenum blendFuncOpenGL(Function func) const;
cvfGLenum blendEquationOpenGL(Equation eq) const;
private:
bool m_enableBlending;
Function m_funcSourceRGB;
Function m_funcDestinationRGB;
Function m_funcSourceAlpha;
Function m_funcDestinationAlpha;
Equation m_equationRGB;
Equation m_equationAlpha;
Color4f m_blendColor;
};
//==================================================================================================
//
// Encapsulate OpenGL glColorMask() function.
//
//==================================================================================================
class ColorMask : public RenderState
{
public:
ColorMask(bool writeAllComponents = true);
void enable(bool writeRed, bool writeGreen, bool writeBlue, bool writeAlpha);
void enableWriteAllComponents(bool writeAllComponents);
bool isRedEnabled() const;
bool isGreenEnabled() const;
bool isBlueEnabled() const;
bool isAlphaEnabled() const;
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
bool m_writeRed;
bool m_writeGreen;
bool m_writeBlue;
bool m_writeAlpha;
};
//==================================================================================================
//
// Encapsulate OpenGL glCullFace() and glEnable(GL_CULL_FACE) functions.
//
//==================================================================================================
class CullFace : public RenderState
{
public:
enum Mode
{
BACK, ///< Cull back facing polygons
FRONT, ///< Cull front facing polygons
FRONT_AND_BACK ///< No polygons are drawn, but other primitives such as points and lines are drawn
};
public:
CullFace(bool enableCulling = true, Mode faceMode = BACK);
void enable(bool enableCulling);
bool isEnabled() const;
void setMode(Mode faceMode);
Mode mode() const;
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
bool m_enableCulling;
Mode m_faceMode;
};
//==================================================================================================
//
// Encapsulate OpenGL glFrontFace().
//
//==================================================================================================
class FrontFace : public RenderState
{
public:
enum Mode
{
CCW, ///< Counterclockwise order (default)
CW ///< Clockwise order
};
public:
FrontFace(Mode faceMode = CCW);
void setMode(Mode faceMode);
Mode mode() const;
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
Mode m_faceMode;
};
//==================================================================================================
//
// Encapsulate OpenGL glEnable(GL_DEPTH_TEST), glDepthFunc() and glDepthMask() functions.
//
//==================================================================================================
class Depth : public RenderState
{
public:
enum Function
{
NEVER, ///< Never passes
LESS, ///< Passes if the incoming depth value is less than the stored depth value. This is the OpenGL default.
EQUAL, ///< Passes if the incoming depth value is equal to the stored depth value.
LEQUAL, ///< Passes if the incoming depth value is less than or equal to the stored depth value.
GREATER, ///< Passes if the incoming depth value is greater than the stored depth value.
NOTEQUAL, ///< Passes if the incoming depth value is not equal to the stored depth value.
GEQUAL, ///< Passes if the incoming depth value is greater than or equal to the stored depth value.
ALWAYS ///< Always passes.
};
public:
Depth(bool depthTest = true, Function func = LESS, bool depthWrite = true);
void setFunction(Function func);
void enableDepthTest(bool enableTest);
void enableDepthWrite(bool enableWrite);
Function function() const;
bool isDepthTestEnabled() const;
bool isDepthWriteEnabled() const;
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
cvfGLenum depthFuncOpenGL() const;
private:
Function m_depthFunc;
bool m_enableDepthTest;
bool m_enableDepthWrite;
};
//==================================================================================================
//
// Controls OpenGL point size, glPointSize() and glEnable()/glDisable() with GL_PROGRAM_POINT_SIZE
//
//==================================================================================================
class Point : public RenderState
{
public:
enum Mode
{
FIXED_SIZE, ///< Fixed diameter of raserized points (as specified by point size/glPointSize())
PROGRAM_SIZE ///< Point size will be specified using GLSL and the gl_PointSize built-in variable
};
public:
Point(Mode sizeMode = FIXED_SIZE);
void setMode(Mode sizeMode);
Mode mode() const;
void enablePointSprite(bool enable);
bool isPointSpriteEnabled() const;
void setSize(float pointSize);
float size() const;
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
Mode m_sizeMode;
bool m_pointSprite;
float m_pointSize;
};
//==================================================================================================
//
// Controls OpenGL polygon rasterization mode, glPolygonMode()
//
//==================================================================================================
class PolygonMode : public RenderState
{
public:
enum Mode
{
FILL, ///< The interior of the polygons is filled
LINE, ///< Boundary edges of the polygons are drawn as line segments
POINT ///< Polygon vertices that are marked as the start of a boundary edge are drawn as points
};
public:
PolygonMode(Mode frontAndBackFaceMode = FILL);
void set(Mode frontAndBackMode);
void setFrontFace(Mode mode);
void setBackFace(Mode mode);
Mode frontFace() const;
Mode backFace() const;
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
static cvfGLenum polygonModeOpenGL(Mode mode);
private:
Mode m_frontFaceMode;
Mode m_backFaceMode;
};
//==================================================================================================
//
// Encapsulate OpenGL glPolygonOffset() and glEnable()/glDisable() with GL_POLYGON_OFFSET_FILL/LINE/POINT
//
//==================================================================================================
class PolygonOffset : public RenderState
{
public:
PolygonOffset();
void enableFillMode(bool enableFill);
void enableLineMode(bool enableLine);
void enablePointMode(bool enablePoint);
bool isFillModeEnabled() const;
bool isLineModeEnabled() const;
bool isPointModeEnabled() const;
void setFactor(float factor);
void setUnits(float units);
float factor() const;
float units() const;
void configurePolygonPositiveOffset();
void configureLineNegativeOffset();
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
float m_factor; // Default value is 0.0
float m_units; // Default value is 0.0
bool m_enableFillMode;
bool m_enableLineMode;
bool m_enablePointMode;
};
//==================================================================================================
//
// Binds a texture and a sampler to a texture unit
//
//==================================================================================================
class TextureBindings : public RenderState
{
public:
TextureBindings();
TextureBindings(Texture* texture, Sampler* sampler, const char* samplerUniformName);
~TextureBindings();
void addBinding(Texture* texture, Sampler* sampler, const char* samplerUniformName);
int bindingCount() const;
Texture* texture(int bindingIdx);
const Texture* texture(int bindingIdx) const;
Sampler* sampler(int bindingIdx);
const Sampler* sampler(int bindingIdx) const;
String samplerUniformName(int bindingIdx) const;
virtual void applyOpenGL(OpenGLContext* oglContext) const;
void setupTextures(OpenGLContext* oglContext);
void applySamplerTextureUnitUniforms(OpenGLContext* oglContext, ShaderProgram* shaderProgram) const;
public:
static const int MAX_TEXTURE_UNITS = 16;
private:
struct BindingEntry
{
ref<Texture> texture;
ref<Sampler> sampler;
String samplerUniformName;
};
BindingEntry m_bindings[MAX_TEXTURE_UNITS];
int m_bindingCount;
};
} // namespace cvf

View File

@ -0,0 +1,256 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfRenderStateBlending.h"
#include "cvfAssert.h"
#include "cvfOpenGL.h"
#include "cvfOpenGLCapabilities.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::RenderStateBlending
/// \ingroup Render
///
/// Encapsulate OpenGL blending functions: glEnable(GL_BLEND), glBlendEquation(), glBlendEquationSeparate()
/// glBlendFunc(), glBlendFuncSeparate(), glBlendColor()
///
/// \sa http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml
/// \sa http://www.opengl.org/sdk/docs/man3/xhtml/glBlendEquation.xml
/// \sa http://www.opengl.org/sdk/docs/man3/xhtml/glBlendEquationSeparate.xml
/// \sa http://www.opengl.org/sdk/docs/man3/xhtml/glBlendFunc.xml
/// \sa http://www.opengl.org/sdk/docs/man3/xhtml/glBlendFuncSeparate.xml
/// \sa http://www.opengl.org/sdk/docs/man3/xhtml/glBlendColor.xml
///
/// \todo
/// Add support for enable/disable blending per drawbuffer: glEnablei(GL_BLEND, drawBufferIndex)
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStateBlending::RenderStateBlending()
: RenderState(BLENDING),
m_enableBlending(false),
m_funcSourceRGB(ONE),
m_funcDestinationRGB(ZERO),
m_funcSourceAlpha(ONE),
m_funcDestinationAlpha(ZERO),
m_equationRGB(FUNC_ADD),
m_equationAlpha(FUNC_ADD),
m_blendColor(0, 0, 0, 0)
{
}
//--------------------------------------------------------------------------------------------------
/// glEnable(GL_BLEND) / glDisable(GL_BLEND)
//--------------------------------------------------------------------------------------------------
void RenderStateBlending::enableBlending(bool blend/*, uint drawBufferIndex*/)
{
m_enableBlending = blend;
}
//--------------------------------------------------------------------------------------------------
/// glBlendFunc()
//--------------------------------------------------------------------------------------------------
void RenderStateBlending::setFunction(Function source, Function destination)
{
m_funcSourceRGB = source;
m_funcSourceAlpha = source;
m_funcDestinationRGB = destination;
m_funcDestinationAlpha = destination;
}
//--------------------------------------------------------------------------------------------------
/// glBlendEquation(). Requires OpenGL 2.0
//--------------------------------------------------------------------------------------------------
void RenderStateBlending::setEquation(Equation eq)
{
m_equationRGB = eq;
m_equationAlpha = eq;
}
//--------------------------------------------------------------------------------------------------
/// glBlendFuncSeparate(). Requires OpenGL 2.0
//--------------------------------------------------------------------------------------------------
void RenderStateBlending::setFunctionSeparate(Function sourceRGB, Function destinationRGB, Function sourceAlpha, Function destinationAlpha)
{
m_funcSourceRGB = sourceRGB;
m_funcDestinationRGB = destinationRGB;
m_funcSourceAlpha = sourceAlpha;
m_funcDestinationAlpha = destinationAlpha;
}
//--------------------------------------------------------------------------------------------------
/// glBlendEquationSeparate(). Requires OpenGL 2.0
//--------------------------------------------------------------------------------------------------
void RenderStateBlending::setEquationSeparate(Equation equationRGB, Equation equationAlpha)
{
m_equationRGB = equationRGB;
m_equationAlpha = equationAlpha;
}
//--------------------------------------------------------------------------------------------------
/// glBlendColor(). Requires OpenGL 2.0
//--------------------------------------------------------------------------------------------------
void RenderStateBlending::setBlendColor(Color4f blendColor)
{
m_blendColor = blendColor;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateBlending::configureTransparencyBlending()
{
m_enableBlending = true;
setFunction(SRC_ALPHA, ONE_MINUS_SRC_ALPHA);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateBlending::applyOpenGL(OpenGLContext* oglContext) const
{
CVF_CALLSITE_OPENGL(oglContext);
/// As we do not care about specific support for OpenGL 1.4, 1.3 etc., everything that is not in 1.1
/// will require at least support for our baseline (currently OpenGL 2.0)
bool openGL2Support = oglContext->capabilities()->supportsOpenGL2();
if (m_enableBlending)
{
glEnable(GL_BLEND);
}
else
{
glDisable(GL_BLEND);
}
if ((m_funcSourceRGB == m_funcSourceAlpha) && (m_funcDestinationRGB == m_funcDestinationAlpha))
{
glBlendFunc(blendFuncOpenGL(m_funcSourceRGB), blendFuncOpenGL(m_funcDestinationRGB));
}
else
{
if (openGL2Support)
{
glBlendFuncSeparate(blendFuncOpenGL(m_funcSourceRGB), blendFuncOpenGL(m_funcDestinationRGB), blendFuncOpenGL(m_funcSourceAlpha), blendFuncOpenGL(m_funcDestinationAlpha));
}
else
{
CVF_LOG_RENDER_ERROR(oglContext, "Context does not support separate blend functions.");
}
}
if (openGL2Support)
{
if (m_equationRGB == m_equationAlpha)
{
glBlendEquation(blendEquationOpenGL(m_equationRGB));
}
else
{
glBlendEquationSeparate(blendEquationOpenGL(m_equationRGB), blendEquationOpenGL(m_equationAlpha));
}
glBlendColor(m_blendColor.r(), m_blendColor.g(), m_blendColor.b(), m_blendColor.a());
}
else
{
// Only error reporting here
if (m_equationRGB != FUNC_ADD ||
m_equationRGB != m_equationAlpha)
{
CVF_LOG_RENDER_ERROR(oglContext, "Context does not support blend equations.");
}
if (m_blendColor != Color4f(0, 0, 0, 0))
{
CVF_LOG_RENDER_ERROR(oglContext, "Context does not support blend color.");
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvfGLenum RenderStateBlending::blendEquationOpenGL(Equation eq) const
{
switch (eq)
{
case FUNC_ADD: return GL_FUNC_ADD;
case FUNC_SUBTRACT: return GL_FUNC_SUBTRACT;
case FUNC_REVERSE_SUBTRACT: return GL_FUNC_REVERSE_SUBTRACT;
#ifndef CVF_OPENGL_ES
case MIN: return GL_MIN;
case MAX: return GL_MAX;
#endif
}
CVF_FAIL_MSG("Unhandled blend equation");
return 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvfGLenum RenderStateBlending::blendFuncOpenGL(Function func) const
{
switch (func)
{
case ZERO: return GL_ZERO;
case ONE: return GL_ONE;
case SRC_COLOR: return GL_SRC_COLOR;
case ONE_MINUS_SRC_COLOR: return GL_ONE_MINUS_SRC_COLOR;
case DST_COLOR: return GL_DST_COLOR;
case ONE_MINUS_DST_COLOR: return GL_ONE_MINUS_DST_COLOR;
case SRC_ALPHA: return GL_SRC_ALPHA;
case ONE_MINUS_SRC_ALPHA: return GL_ONE_MINUS_SRC_ALPHA;
case DST_ALPHA: return GL_DST_ALPHA;
case ONE_MINUS_DST_ALPHA: return GL_ONE_MINUS_DST_ALPHA;
case CONSTANT_COLOR: return GL_CONSTANT_COLOR;
case ONE_MINUS_CONSTANT_COLOR: return GL_ONE_MINUS_CONSTANT_COLOR;
case CONSTANT_ALPHA: return GL_CONSTANT_ALPHA;
case ONE_MINUS_CONSTANT_ALPHA: return GL_ONE_MINUS_CONSTANT_ALPHA;
case SRC_ALPHA_SATURATE: return GL_SRC_ALPHA_SATURATE;
}
CVF_FAIL_MSG("Unhandled blend func");
return 0;
}
} // namespace cvf

View File

@ -0,0 +1,99 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#pragma once
#include "cvfRenderState.h"
#include "cvfOpenGLTypes.h"
#include "cvfColor4.h"
namespace cvf {
//==================================================================================================
//
// Controls OpenGL blending
//
//==================================================================================================
class RenderStateBlending : public RenderState
{
public:
enum Function
{
ZERO,
ONE,
SRC_COLOR,
ONE_MINUS_SRC_COLOR,
DST_COLOR,
ONE_MINUS_DST_COLOR,
SRC_ALPHA,
ONE_MINUS_SRC_ALPHA,
DST_ALPHA,
ONE_MINUS_DST_ALPHA,
CONSTANT_COLOR,
ONE_MINUS_CONSTANT_COLOR,
CONSTANT_ALPHA,
ONE_MINUS_CONSTANT_ALPHA,
SRC_ALPHA_SATURATE
};
enum Equation
{
FUNC_ADD,
FUNC_SUBTRACT,
FUNC_REVERSE_SUBTRACT,
MIN, // Unsupported on OpenGL ES
MAX // Unsupported on OpenGL ES
};
public:
RenderStateBlending();
void enableBlending(bool blend);
void setFunction(Function source, Function destination);
void setEquation(Equation equation);
void setFunctionSeparate(Function sourceRGB, Function destinationRGB, Function sourceAlpha, Function destinationAlpha);
void setEquationSeparate(Equation equationRGB, Equation equationAlpha);
void setBlendColor(Color4f blendColor);
void configureTransparencyBlending();
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
cvfGLenum blendFuncOpenGL(Function func) const;
cvfGLenum blendEquationOpenGL(Equation eq) const;
private:
bool m_enableBlending;
Function m_funcSourceRGB;
Function m_funcDestinationRGB;
Function m_funcSourceAlpha;
Function m_funcDestinationAlpha;
Equation m_equationRGB;
Equation m_equationAlpha;
Color4f m_blendColor;
};
} // namespace cvf

View File

@ -0,0 +1,130 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfRenderStateColorMask.h"
#include "cvfAssert.h"
#include "cvfOpenGL.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::RenderStateColorMask
/// \ingroup Render
///
/// Encapsulate OpenGL glColorMask() function.
///
/// \sa http://www.opengl.org/sdk/docs/man/xhtml/glColorMask.xml
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStateColorMask::RenderStateColorMask(bool writeAllComponents)
: RenderState(COLOR_MASK),
m_writeRed(writeAllComponents),
m_writeGreen(writeAllComponents),
m_writeBlue(writeAllComponents),
m_writeAlpha(writeAllComponents)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateColorMask::enable(bool writeRed, bool writeGreen, bool writeBlue, bool writeAlpha)
{
m_writeRed = writeRed;
m_writeGreen = writeGreen;
m_writeBlue = writeBlue;
m_writeAlpha = writeAlpha;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateColorMask::enableWriteAllComponents(bool writeAllComponents)
{
m_writeRed = writeAllComponents;
m_writeGreen = writeAllComponents;
m_writeBlue = writeAllComponents;
m_writeAlpha = writeAllComponents;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RenderStateColorMask::isRedEnabled() const
{
return m_writeRed;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RenderStateColorMask::isGreenEnabled() const
{
return m_writeGreen;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RenderStateColorMask::isBlueEnabled() const
{
return m_writeBlue;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RenderStateColorMask::isAlphaEnabled() const
{
return m_writeAlpha;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateColorMask::applyOpenGL(OpenGLContext* oglContext) const
{
GLboolean writeRed = m_writeRed ? static_cast<GLboolean>(GL_TRUE) : static_cast<GLboolean>(GL_FALSE);
GLboolean writeGreen = m_writeGreen ? static_cast<GLboolean>(GL_TRUE) : static_cast<GLboolean>(GL_FALSE);
GLboolean writeBlue = m_writeBlue ? static_cast<GLboolean>(GL_TRUE) : static_cast<GLboolean>(GL_FALSE);
GLboolean writeAlpha = m_writeAlpha ? static_cast<GLboolean>(GL_TRUE) : static_cast<GLboolean>(GL_FALSE);
glColorMask(writeRed, writeGreen, writeBlue, writeAlpha);
CVF_CHECK_OGL(oglContext);
}
} // namespace cvf

View File

@ -0,0 +1,55 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#pragma once
#include "cvfRenderState.h"
namespace cvf {
//==================================================================================================
//
// Encapsulate OpenGL glColorMask() function.
//
//==================================================================================================
class RenderStateColorMask : public RenderState
{
public:
RenderStateColorMask(bool writeAllComponents = true);
void enable(bool writeRed, bool writeGreen, bool writeBlue, bool writeAlpha);
void enableWriteAllComponents(bool writeAllComponents);
bool isRedEnabled() const;
bool isGreenEnabled() const;
bool isBlueEnabled() const;
bool isAlphaEnabled() const;
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
bool m_writeRed;
bool m_writeGreen;
bool m_writeBlue;
bool m_writeAlpha;
};
} // namespace cvf

View File

@ -0,0 +1,120 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfRenderStateCullFace.h"
#include "cvfAssert.h"
#include "cvfOpenGL.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::RenderStateCullFace
/// \ingroup Render
///
/// Encapsulate OpenGL glCullFace() and glEnable(GL_CULL_FACE) functions.
///
/// \sa http://www.opengl.org/sdk/docs/man/xhtml/glCullFace.xml
/// \sa http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStateCullFace::RenderStateCullFace(bool enableCulling, Mode faceMode)
: RenderState(CULL_FACE),
m_enableCulling(enableCulling),
m_faceMode(faceMode)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateCullFace::enable(bool enableCulling)
{
m_enableCulling = enableCulling;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RenderStateCullFace::isEnabled() const
{
return m_enableCulling;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateCullFace::setMode(Mode faceMode)
{
m_faceMode = faceMode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStateCullFace::Mode RenderStateCullFace::mode() const
{
return m_faceMode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateCullFace::applyOpenGL(OpenGLContext* oglContext) const
{
if (m_enableCulling)
{
if (m_faceMode == BACK)
{
glCullFace(GL_BACK);
}
else if (m_faceMode == FRONT)
{
glCullFace(GL_FRONT);
}
else
{
glCullFace(GL_FRONT_AND_BACK);
}
glEnable(GL_CULL_FACE);
}
else
{
glDisable(GL_CULL_FACE);
}
CVF_CHECK_OGL(oglContext);
}
} // namespace cvf

View File

@ -0,0 +1,60 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#pragma once
#include "cvfRenderState.h"
namespace cvf {
//==================================================================================================
//
// Encapsulate OpenGL glCullFace() and glEnable(GL_CULL_FACE) functions.
//
//==================================================================================================
class RenderStateCullFace : public RenderState
{
public:
enum Mode
{
BACK, ///< Cull back facing polygons
FRONT, ///< Cull front facing polygons
FRONT_AND_BACK ///< No polygons are drawn, but other primitives such as points and lines are drawn
};
public:
RenderStateCullFace(bool enableCulling = true, Mode faceMode = BACK);
void enable(bool enableCulling);
bool isEnabled() const;
void setMode(Mode faceMode);
Mode mode() const;
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
bool m_enableCulling;
Mode m_faceMode;
};
} // namespace cvf

View File

@ -0,0 +1,173 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfRenderStateDepth.h"
#include "cvfAssert.h"
#include "cvfOpenGL.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::RenderStateDepth
/// \ingroup Render
///
/// Encapsulate OpenGL glEnable(GL_DEPTH_TEST), glDepthFunc() and glDepthMask() functions.
///
/// \sa http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml
/// \sa http://www.opengl.org/sdk/docs/man/xhtml/glDepthFunc.xml
/// \sa http://www.opengl.org/sdk/docs/man/xhtml/glDepthMask.xml
///
/// \todo
/// Add support for glDepthRange() if needed.
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStateDepth::RenderStateDepth(bool depthTest, Function func, bool depthWrite)
: RenderState(DEPTH)
{
m_enableDepthTest = depthTest;
m_depthFunc = func;
m_enableDepthWrite = depthWrite;
}
//--------------------------------------------------------------------------------------------------
/// Specifies the depth comparison function.
///
/// \sa http://www.opengl.org/sdk/docs/man/xhtml/glDepthFunc.xml
//--------------------------------------------------------------------------------------------------
void RenderStateDepth::setFunction(Function func)
{
m_depthFunc = func;
}
//--------------------------------------------------------------------------------------------------
/// Enable or disable depth testing and updating of the depth buffer.
///
/// \param enableTest Specify true to enable testing against and updating of depth buffer.
///
/// \sa http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml with GL_DEPTH_TEST
///
/// From OpenGL docs:
/// If enabled, do depth comparisons and update the depth buffer. Note that even if the depth buffer
/// exists and the depth mask is non-zero, the depth buffer is not updated if the depth test is disabled
//--------------------------------------------------------------------------------------------------
void RenderStateDepth::enableDepthTest(bool enableTest)
{
m_enableDepthTest = enableTest;
}
//--------------------------------------------------------------------------------------------------
/// Enable or disable writing into the depth buffer
///
/// \param enableWrite Specify true to enable writing to depth buffer, false to disable. The default is true.
///
/// \sa http://www.opengl.org/sdk/docs/man/xhtml/glDepthMask.xml
//--------------------------------------------------------------------------------------------------
void RenderStateDepth::enableDepthWrite(bool enableWrite)
{
m_enableDepthWrite = enableWrite;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStateDepth::Function RenderStateDepth::function() const
{
return m_depthFunc;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RenderStateDepth::isDepthTestEnabled() const
{
return m_enableDepthTest;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RenderStateDepth::isDepthWriteEnabled() const
{
return m_enableDepthWrite;
}
//--------------------------------------------------------------------------------------------------
/// Specify the depth setting to OpenGL.
//--------------------------------------------------------------------------------------------------
void RenderStateDepth::applyOpenGL(OpenGLContext* oglContext) const
{
if (m_enableDepthTest)
{
GLenum depthFuncOGL = depthFuncOpenGL();
glDepthFunc(depthFuncOGL);
GLboolean enableDepthWrite = m_enableDepthWrite ? static_cast<GLboolean>(GL_TRUE) : static_cast<GLboolean>(GL_FALSE);
glDepthMask(enableDepthWrite);
glEnable(GL_DEPTH_TEST);
}
else
{
glDisable(GL_DEPTH_TEST);
}
CVF_CHECK_OGL(oglContext);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvfGLenum RenderStateDepth::depthFuncOpenGL() const
{
switch (m_depthFunc)
{
case NEVER: return GL_NEVER;
case LESS: return GL_LESS;
case EQUAL: return GL_EQUAL;
case LEQUAL: return GL_LEQUAL;
case GREATER: return GL_GREATER;
case NOTEQUAL: return GL_NOTEQUAL;
case GEQUAL: return GL_GEQUAL;
case ALWAYS: return GL_ALWAYS;
}
CVF_FAIL_MSG("Unhandled depth func");
return 0;
}
} // namespace cvf

View File

@ -0,0 +1,70 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#pragma once
#include "cvfRenderState.h"
#include "cvfOpenGLTypes.h"
namespace cvf {
//==================================================================================================
//
// Encapsulate OpenGL glEnable(GL_DEPTH_TEST), glDepthFunc() and glDepthMask() functions.
//
//==================================================================================================
class RenderStateDepth : public RenderState
{
public:
enum Function
{
NEVER, ///< Never passes
LESS, ///< Passes if the incoming depth value is less than the stored depth value. This is the OpenGL default.
EQUAL, ///< Passes if the incoming depth value is equal to the stored depth value.
LEQUAL, ///< Passes if the incoming depth value is less than or equal to the stored depth value.
GREATER, ///< Passes if the incoming depth value is greater than the stored depth value.
NOTEQUAL, ///< Passes if the incoming depth value is not equal to the stored depth value.
GEQUAL, ///< Passes if the incoming depth value is greater than or equal to the stored depth value.
ALWAYS ///< Always passes.
};
public:
RenderStateDepth(bool depthTest = true, Function func = LESS, bool depthWrite = true);
void setFunction(Function func);
void enableDepthTest(bool enableTest);
void enableDepthWrite(bool enableWrite);
Function function() const;
bool isDepthTestEnabled() const;
bool isDepthWriteEnabled() const;
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
cvfGLenum depthFuncOpenGL() const;
private:
Function m_depthFunc;
bool m_enableDepthTest;
bool m_enableDepthWrite;
};
} // namespace cvf

View File

@ -0,0 +1,89 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfRenderStateFrontFace.h"
#include "cvfAssert.h"
#include "cvfOpenGL.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::RenderStateFrontFace
/// \ingroup Render
///
/// Encapsulate OpenGL glFrontFace() used to specify polygon winding. Used together with RenderStateCullFace
/// render state and the gl_FrontFacing bultin shader input variable.
///
/// \sa http://www.opengl.org/sdk/docs/man/xhtml/glFrontFace.xml
/// \sa http://www.opengl.org/sdk/docs/manglsl/xhtml/gl_FrontFacing.xml
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStateFrontFace::RenderStateFrontFace(Mode faceMode)
: RenderState(FRONT_FACE),
m_faceMode(faceMode)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateFrontFace::setMode(Mode faceMode)
{
m_faceMode = faceMode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStateFrontFace::Mode RenderStateFrontFace::mode() const
{
return m_faceMode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateFrontFace::applyOpenGL(OpenGLContext* oglContext) const
{
if (m_faceMode == CW)
{
glFrontFace(GL_CW);
}
else
{
glFrontFace(GL_CCW);
}
CVF_CHECK_OGL(oglContext);
}
} // namespace cvf

View File

@ -19,30 +19,37 @@
#pragma once
#include "cvfBase.h"
#include "cvfObject.h"
#include "cvfArray.h"
#include "cvfScalarMapper.h"
#include <vector>
#include "cvfRenderState.h"
namespace cvf {
//==================================================================================================
//
// Abstract base class for scalar mappers that communicate with a legend
// Encapsulate OpenGL glFrontFace().
//
//==================================================================================================
class LegendScalarMapper : public ScalarMapper
class RenderStateFrontFace : public RenderState
{
public:
// Return a the set of domain values representing sensible major tickmarks
virtual void majorLevels(std::vector<double>* domainValues) const = 0;
// Return the normalized (0.0, 1.0) representation of the domainValue
virtual double normalizedLevelPosition(double domainValue) const = 0;
// Return the domain value from a normalized val
virtual double domainValue(double normalizedPosition) const = 0;
enum Mode
{
CCW, ///< Counterclockwise order (default)
CW ///< Clockwise order
};
public:
RenderStateFrontFace(Mode faceMode = CCW);
void setMode(Mode faceMode);
Mode mode() const;
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
Mode m_faceMode;
};
}
} // namespace cvf

View File

@ -0,0 +1,110 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfRenderStateLine.h"
#include "cvfAssert.h"
#include "cvfOpenGL.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::RenderStateLine
/// \ingroup Render
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStateLine::RenderStateLine(float lineWidth)
: RenderState(LINE),
m_lineWidth(lineWidth),
m_smooth(false)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateLine::setWidth(float lineWidth)
{
m_lineWidth = lineWidth;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float RenderStateLine::width() const
{
return m_lineWidth;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateLine::enableSmooth(bool enableSmooth)
{
m_smooth = enableSmooth;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RenderStateLine::isSmoothEnabled() const
{
return m_smooth;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateLine::applyOpenGL(OpenGLContext* oglContext) const
{
CVF_UNUSED(oglContext);
glLineWidth(m_lineWidth);
#ifndef CVF_OPENGL_ES
if (m_smooth)
{
glEnable(GL_LINE_SMOOTH);
}
else
{
glDisable(GL_LINE_SMOOTH);
}
#endif
}
} // namespace cvf

View File

@ -0,0 +1,51 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#pragma once
#include "cvfRenderState.h"
namespace cvf {
//==================================================================================================
//
// Controls OpenGL linewidth and aliasing, glLineWidth() and glEnable()/glDisable() with GL_LINE SMOOTH
//
//==================================================================================================
class RenderStateLine : public RenderState
{
public:
RenderStateLine(float lineWidth = 1.0f);
void setWidth(float lineWidth);
float width() const;
void enableSmooth(bool enableSmooth);
bool isSmoothEnabled() const;
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
float m_lineWidth;
bool m_smooth;
};
} // namespace cvf

View File

@ -0,0 +1,165 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfRenderStatePoint.h"
#include "cvfAssert.h"
#include "cvfOpenGL.h"
#include "cvfOpenGLCapabilities.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::RenderStatePoint
/// \ingroup Render
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStatePoint::RenderStatePoint(Mode sizeMode)
: RenderState(POINT),
m_sizeMode(sizeMode),
m_pointSprite(false),
m_pointSize(1.0f)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStatePoint::setMode(Mode sizeMode)
{
m_sizeMode = sizeMode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStatePoint::Mode RenderStatePoint::mode() const
{
return m_sizeMode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStatePoint::enablePointSprite(bool enable)
{
m_pointSprite = enable;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RenderStatePoint::isPointSpriteEnabled() const
{
return m_pointSprite;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStatePoint::setSize(float pointSize)
{
m_pointSize = pointSize;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float RenderStatePoint::size() const
{
return m_pointSize;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStatePoint::applyOpenGL(OpenGLContext* oglContext) const
{
CVF_CALLSITE_OPENGL(oglContext);
// OpenGL ES does not support fixed point size
// Point size is always specified using GLSL's gl_PointSize
#ifndef CVF_OPENGL_ES
bool openGL2Support = oglContext->capabilities()->supportsOpenGL2();
if (m_sizeMode == FIXED_SIZE)
{
if (openGL2Support)
{
glDisable(GL_PROGRAM_POINT_SIZE);
}
glPointSize(m_pointSize);
}
else
{
if (openGL2Support)
{
glEnable(GL_PROGRAM_POINT_SIZE);
}
else
{
CVF_LOG_RENDER_ERROR(oglContext, "Context does not support program point size.");
}
}
if (openGL2Support)
{
if (m_pointSprite)
{
glEnable(GL_POINT_SPRITE);
glPointParameteri(GL_POINT_SPRITE_COORD_ORIGIN, GL_LOWER_LEFT);
}
else
{
glDisable(GL_POINT_SPRITE);
}
}
else
{
if (m_pointSprite)
{
CVF_LOG_RENDER_ERROR(oglContext, "Context does not support point sprites.");
}
}
#endif
CVF_CHECK_OGL(oglContext);
}
} // namespace cvf

View File

@ -0,0 +1,61 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#pragma once
#include "cvfRenderState.h"
namespace cvf {
//==================================================================================================
//
// Controls OpenGL point size, glPointSize() and glEnable()/glDisable() with GL_PROGRAM_POINT_SIZE
//
//==================================================================================================
class RenderStatePoint : public RenderState
{
public:
enum Mode
{
FIXED_SIZE, ///< Fixed diameter of raserized points (as specified by point size/glPointSize())
PROGRAM_SIZE ///< Point size will be specified using GLSL and the gl_PointSize built-in variable
};
public:
RenderStatePoint(Mode sizeMode = FIXED_SIZE);
void setMode(Mode sizeMode);
Mode mode() const;
void enablePointSprite(bool enable);
bool isPointSpriteEnabled() const;
void setSize(float pointSize);
float size() const;
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
Mode m_sizeMode;
bool m_pointSprite;
float m_pointSize;
};
} // namespace cvf

View File

@ -0,0 +1,135 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfRenderStatePolygonMode.h"
#include "cvfOpenGL.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::RenderStatePolygonMode
/// \ingroup Render
///
///
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStatePolygonMode::RenderStatePolygonMode(Mode frontAndBackFaceMode)
: RenderState(POLYGON_MODE),
m_frontFaceMode(frontAndBackFaceMode),
m_backFaceMode(frontAndBackFaceMode)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStatePolygonMode::set(Mode frontAndBackMode)
{
m_frontFaceMode = frontAndBackMode;
m_backFaceMode = frontAndBackMode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStatePolygonMode::setFrontFace(Mode mode)
{
m_frontFaceMode = mode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStatePolygonMode::setBackFace(Mode mode)
{
m_backFaceMode = mode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStatePolygonMode::Mode RenderStatePolygonMode::frontFace() const
{
return m_frontFaceMode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStatePolygonMode::Mode RenderStatePolygonMode::backFace() const
{
return m_backFaceMode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStatePolygonMode::applyOpenGL(OpenGLContext* oglContext) const
{
#ifndef CVF_OPENGL_ES
if (m_frontFaceMode == m_backFaceMode)
{
glPolygonMode(GL_FRONT_AND_BACK, polygonModeOpenGL(m_frontFaceMode));
}
else
{
glPolygonMode(GL_FRONT, polygonModeOpenGL(m_frontFaceMode));
glPolygonMode(GL_BACK, polygonModeOpenGL(m_backFaceMode));
}
#endif
CVF_CHECK_OGL(oglContext);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvfGLenum RenderStatePolygonMode::polygonModeOpenGL(Mode mode)
{
switch (mode)
{
#ifndef CVF_OPENGL_ES
case FILL: return GL_FILL;
case LINE: return GL_LINE;
case POINT: return GL_POINT;
default: CVF_FAIL_MSG("Unhandled polygon mode");
#endif
}
return 0;
}
} // namespace cvf

View File

@ -0,0 +1,65 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#pragma once
#include "cvfRenderState.h"
#include "cvfOpenGLTypes.h"
#include "cvfColor4.h"
namespace cvf {
//==================================================================================================
//
// Controls OpenGL polygon rasterization mode, glPolygonMode()
//
//==================================================================================================
class RenderStatePolygonMode : public RenderState
{
public:
enum Mode
{
FILL, ///< The interior of the polygons is filled
LINE, ///< Boundary edges of the polygons are drawn as line segments
POINT ///< Polygon vertices that are marked as the start of a boundary edge are drawn as points
};
public:
RenderStatePolygonMode(Mode frontAndBackFaceMode = FILL);
void set(Mode frontAndBackMode);
void setFrontFace(Mode mode);
void setBackFace(Mode mode);
Mode frontFace() const;
Mode backFace() const;
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
static cvfGLenum polygonModeOpenGL(Mode mode);
private:
Mode m_frontFaceMode;
Mode m_backFaceMode;
};
} // namespace cvf

View File

@ -0,0 +1,196 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfAssert.h"
#include "cvfRenderStatePolygonOffset.h"
#include "cvfOpenGL.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::RenderStatePolygonOffset
/// \ingroup Render
///
/// Encapsulate OpenGL glPolygonOffset() and glEnable()/glDisable() with GL_POLYGON_OFFSET_FILL/LINE/POINT
///
/// \sa http://www.opengl.org/sdk/docs/man/xhtml/glPolygonOffset.xml
/// \sa http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml
///
//==================================================================================================
RenderStatePolygonOffset::RenderStatePolygonOffset()
: RenderState(POLYGON_OFFSET),
m_factor(0.0f),
m_units(0.0f),
m_enableFillMode(false),
m_enableLineMode(false),
m_enablePointMode(false)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStatePolygonOffset::enableFillMode(bool enableFill)
{
m_enableFillMode = enableFill;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStatePolygonOffset::enableLineMode(bool enableLine)
{
m_enableLineMode = enableLine;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStatePolygonOffset::enablePointMode(bool enablePoint)
{
m_enablePointMode = enablePoint;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RenderStatePolygonOffset::isFillModeEnabled() const
{
return m_enableFillMode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RenderStatePolygonOffset::isLineModeEnabled() const
{
return m_enableLineMode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool RenderStatePolygonOffset::isPointModeEnabled() const
{
return m_enablePointMode;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStatePolygonOffset::setFactor(float factor)
{
m_factor = factor;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStatePolygonOffset::setUnits(float units)
{
m_units = units;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float RenderStatePolygonOffset::factor() const
{
return m_factor;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float RenderStatePolygonOffset::units() const
{
return m_units;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStatePolygonOffset::configurePolygonPositiveOffset()
{
m_enableFillMode = true;
m_enableLineMode = false;
m_enablePointMode = false;
m_factor = 1.0;
m_units = 1.0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStatePolygonOffset::configureLineNegativeOffset()
{
m_enableFillMode = false;
m_enableLineMode = true;
m_enablePointMode = false;
m_factor = -1.0;
m_units = -1.0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStatePolygonOffset::applyOpenGL(OpenGLContext* oglContext) const
{
if (m_enableFillMode ||
m_enableLineMode ||
m_enablePointMode)
{
glPolygonOffset(m_factor, m_units);
}
if (m_enableFillMode) glEnable(GL_POLYGON_OFFSET_FILL);
else glDisable(GL_POLYGON_OFFSET_FILL);
#ifndef CVF_OPENGL_ES
if (m_enableLineMode) glEnable(GL_POLYGON_OFFSET_LINE);
else glDisable(GL_POLYGON_OFFSET_LINE);
if (m_enablePointMode) glEnable(GL_POLYGON_OFFSET_POINT);
else glDisable(GL_POLYGON_OFFSET_POINT);
#endif
CVF_CHECK_OGL(oglContext);
}
} // namespace cvf

View File

@ -0,0 +1,66 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#pragma once
#include "cvfRenderState.h"
#include "cvfOpenGLTypes.h"
#include "cvfColor4.h"
namespace cvf {
//==================================================================================================
//
// Encapsulate OpenGL glPolygonOffset() and glEnable()/glDisable() with GL_POLYGON_OFFSET_FILL/LINE/POINT
//
//==================================================================================================
class RenderStatePolygonOffset : public RenderState
{
public:
RenderStatePolygonOffset();
void enableFillMode(bool enableFill);
void enableLineMode(bool enableLine);
void enablePointMode(bool enablePoint);
bool isFillModeEnabled() const;
bool isLineModeEnabled() const;
bool isPointModeEnabled() const;
void setFactor(float factor);
void setUnits(float units);
float factor() const;
float units() const;
void configurePolygonPositiveOffset();
void configureLineNegativeOffset();
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
float m_factor; // Default value is 0.0
float m_units; // Default value is 0.0
bool m_enableFillMode;
bool m_enableLineMode;
bool m_enablePointMode;
};
} // namespace cvf

View File

@ -0,0 +1,159 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfRenderStateStencil.h"
#include "cvfAssert.h"
#include "cvfOpenGL.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::RenderStateStencil
/// \ingroup Render
///
/// glStencilFunc(), glStencilOp() and glEnable(GL_STENCIL_TEST) functions.
///
/// \sa http://www.opengl.org/sdk/docs/man/xhtml/glStencilFunc.xml
/// \sa http://www.opengl.org/sdk/docs/man/xhtml/glStencilOp.xml
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStateStencil::RenderStateStencil()
: RenderState(STENCIL),
m_function(ALWAYS),
m_functionRefValue(0),
m_functionMask(0xffffffff),
m_opStencilFails(KEEP),
m_opStencilPassesDepthFails(KEEP),
m_opStencilPassesDepthPasses(KEEP),
m_enable(false)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateStencil::enableStencilTest(bool enableTest)
{
m_enable = enableTest;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateStencil::setFunction(Function func, int refValue, uint mask)
{
m_function = func;
m_functionRefValue = refValue;
m_functionMask = mask;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateStencil::setOperation(Operation stencilFails, Operation stencilPassesDepthFails, Operation stencilPassesDepthPasses)
{
m_opStencilFails = stencilFails;
m_opStencilPassesDepthFails = stencilPassesDepthFails;
m_opStencilPassesDepthPasses = stencilPassesDepthPasses;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateStencil::applyOpenGL(OpenGLContext* oglContext) const
{
if (m_enable)
{
GLenum funcOGL = functionOpenGL(m_function);
glStencilFunc(funcOGL, m_functionRefValue, m_functionMask);
const GLenum stencilFailsOGL = operationOpenGL(m_opStencilFails);
const GLenum stencilPassesDepthFails = operationOpenGL(m_opStencilPassesDepthFails);
const GLenum stencilPassesDepthPasses = operationOpenGL(m_opStencilPassesDepthPasses);
glStencilOp(stencilFailsOGL, stencilPassesDepthFails, stencilPassesDepthPasses);
glEnable(GL_STENCIL_TEST);
}
else
{
glDisable(GL_STENCIL_TEST);
}
CVF_CHECK_OGL(oglContext);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::cvfGLenum RenderStateStencil::functionOpenGL(Function func)
{
switch (func)
{
case NEVER: return GL_NEVER;
case LESS: return GL_LESS;
case LEQUAL: return GL_LEQUAL;
case GREATER: return GL_GREATER;
case GEQUAL: return GL_GEQUAL;
case EQUAL: return GL_EQUAL;
case NOTEQUAL: return GL_NOTEQUAL;
case ALWAYS: return GL_ALWAYS;
}
CVF_FAIL_MSG("Unhandled stencil func");
return 0;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
cvf::cvfGLenum RenderStateStencil::operationOpenGL(Operation op)
{
switch (op)
{
case KEEP: return GL_KEEP;
case ZERO: return GL_ZERO;
case REPLACE: return GL_REPLACE;
case INCR: return GL_INCR;
case INCR_WRAP: return GL_INCR_WRAP;
case DECR: return GL_DECR;
case DECR_WRAP: return GL_DECR_WRAP;
case INVERT: return GL_INVERT;
}
CVF_FAIL_MSG("Unhandled stencil operation");
return 0;
}
} // namespace cvf

View File

@ -0,0 +1,84 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#pragma once
#include "cvfRenderState.h"
#include "cvfOpenGLTypes.h"
namespace cvf {
//==================================================================================================
//
// Encapsulate OpenGL glStencilFunc(), glStencilOp() and glEnable(GL_STENCIL_TEST) functions.
//
//==================================================================================================
class RenderStateStencil : public RenderState
{
public:
enum Function
{
NEVER, ///< Always fails.
LESS, ///< Passes if ( ref & mask ) < ( stencil & mask ).
LEQUAL, ///< Passes if ( ref & mask ) <= ( stencil & mask ).
GREATER, ///< Passes if ( ref & mask ) > ( stencil & mask ).
GEQUAL, ///< Passes if ( ref & mask ) >= ( stencil & mask ).
EQUAL, ///< Passes if ( ref & mask ) = ( stencil & mask ).
NOTEQUAL, ///< Passes if ( ref & mask ) != ( stencil & mask ).
ALWAYS ///< Always passes.
};
enum Operation
{
KEEP, ///< Keeps the current value.
ZERO, ///< Sets the stencil buffer value to 0.
REPLACE, ///< Sets the stencil buffer value to ref, as specified by glStencilFunc.
INCR, ///< Increments the current stencil buffer value. Clamps to the maximum representable unsigned value.
INCR_WRAP, ///< Increments the current stencil buffer value. Wraps stencil buffer value to zero when incrementing the maximum representable unsigned value.
DECR, ///< Decrements the current stencil buffer value. Clamps to 0.
DECR_WRAP, ///< Decrements the current stencil buffer value. Wraps stencil buffer value to the maximum representable unsigned value when decrementing a stencil buffer value of zero.
INVERT ///< Bitwise inverts the current stencil buffer value.
};
public:
RenderStateStencil();
void enableStencilTest(bool enableTest);
void setFunction(Function func, int refValue, uint mask);
void setOperation(Operation stencilFails, Operation stencilPassesDepthFails, Operation stencilPassesDepthPasses);
virtual void applyOpenGL(OpenGLContext* oglContext) const;
private:
private:
static cvfGLenum functionOpenGL(Function func);
static cvfGLenum operationOpenGL(Operation op);
private:
Function m_function; // Stencil test function. Initial value ALWAYS
int m_functionRefValue; // Reference value for the stencil test. Initial value is 0
uint m_functionMask; // Mask that is ANDed with both the reference value and the stored stencil value when the test is done. Initial value is all 1's
Operation m_opStencilFails; // Action to take when the stencil test fails. Initial value is KEEP.
Operation m_opStencilPassesDepthFails; // Stencil action when the stencil test passes, but the depth test fails. Initial value is KEEP
Operation m_opStencilPassesDepthPasses; // Stencil action when both the stencil test and the depth test passes. Initial value is KEEP
bool m_enable; // Enable/disable the stencil test
};
} // namespace cvf

View File

@ -0,0 +1,251 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#include "cvfBase.h"
#include "cvfRenderStateTextureBindings.h"
#include "cvfAssert.h"
#include "cvfOpenGL.h"
#include "cvfUniform.h"
#include "cvfShaderProgram.h"
#include "cvfTexture.h"
#include "cvfSampler.h"
#include "cvfOpenGLCapabilities.h"
namespace cvf {
//==================================================================================================
///
/// \class cvf::RenderStateTextureBindings
/// \ingroup Render
///
/// \warning Requires OpenGL2 support
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStateTextureBindings::RenderStateTextureBindings()
: RenderState(TEXTURE_BINDINGS),
m_bindingCount(0)
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStateTextureBindings::RenderStateTextureBindings(Texture* texture, Sampler* sampler, const char* samplerUniformName)
: RenderState(TEXTURE_BINDINGS),
m_bindingCount(0)
{
addBinding(texture, sampler, samplerUniformName);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
RenderStateTextureBindings::~RenderStateTextureBindings()
{
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateTextureBindings::addBinding(Texture* texture, Sampler* sampler, const char* samplerUniformName)
{
CVF_ASSERT(m_bindingCount < MAX_TEXTURE_UNITS - 1);
CVF_ASSERT(texture && sampler && samplerUniformName);
m_bindings[m_bindingCount].sampler = sampler;
m_bindings[m_bindingCount].texture = texture;
m_bindings[m_bindingCount].samplerUniformName = samplerUniformName;
m_bindingCount++;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
int RenderStateTextureBindings::bindingCount() const
{
return m_bindingCount;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Texture* RenderStateTextureBindings::texture(int bindingIdx)
{
CVF_ASSERT(bindingIdx >= 0 && bindingIdx < m_bindingCount);
return m_bindings[bindingIdx].texture.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const Texture* RenderStateTextureBindings::texture(int bindingIdx) const
{
CVF_ASSERT(bindingIdx >= 0 && bindingIdx < m_bindingCount);
return m_bindings[bindingIdx].texture.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
const Sampler* RenderStateTextureBindings::sampler(int bindingIdx) const
{
CVF_ASSERT(bindingIdx >= 0 && bindingIdx < m_bindingCount);
return m_bindings[bindingIdx].sampler.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Sampler* RenderStateTextureBindings::sampler(int bindingIdx)
{
CVF_ASSERT(bindingIdx >= 0 && bindingIdx < m_bindingCount);
return m_bindings[bindingIdx].sampler.p();
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
String RenderStateTextureBindings::samplerUniformName(int bindingIdx) const
{
CVF_ASSERT(bindingIdx >= 0 && bindingIdx < m_bindingCount);
return m_bindings[bindingIdx].samplerUniformName;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateTextureBindings::setupTextures(OpenGLContext* oglContext)
{
CVF_CALLSITE_OPENGL(oglContext);
const OpenGLCapabilities* oglCaps = oglContext->capabilities();
if (!oglCaps->supportsOpenGL2())
{
CVF_LOG_RENDER_ERROR(oglContext, "Context does not support texture setup using RenderStateTextureBindings.");
return;
}
glActiveTexture(GL_TEXTURE0);
int i;
for (i = 0; i < m_bindingCount; i++)
{
Texture* texture = m_bindings[i].texture.p();
if (texture->textureOglId() == 0)
{
glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + i));
texture->setupTexture(oglContext);
CVF_CHECK_OGL(oglContext);
}
else
{
// Handle case where mipmap generation is enabled, but the mipmaps are not present
// This will typically happen if the texture has been rendered to using an FBO
// In that case the texture exists, but no mipmaps have yet been generated
if (texture->isMipmapGenerationEnabled() && !texture->hasMipmap())
{
if (oglCaps->hasCapability(OpenGLCapabilities::GENERATE_MIPMAP_FUNC))
{
glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + i));
texture->generateMipmap(oglContext);
CVF_CHECK_OGL(oglContext);
}
else
{
CVF_LOG_RENDER_ERROR(oglContext, "Context does not support explicit mipmap generation.");
}
}
}
}
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateTextureBindings::applyOpenGL(OpenGLContext* oglContext) const
{
CVF_CALLSITE_OPENGL(oglContext);
// The apply function needs to work for all contexts in its default state
// so just return if no bindings have been set
if (m_bindingCount == 0)
{
return;
}
if (!oglContext->capabilities()->supportsOpenGL2())
{
CVF_LOG_RENDER_ERROR(oglContext, "Context does not support TextureBinding application.");
return;
}
int i;
for (i = 0; i < m_bindingCount; i++)
{
const Texture* texture = m_bindings[i].texture.p();
const Sampler* sampler = m_bindings[i].sampler.p();
CVF_ASSERT(texture && sampler);
glActiveTexture(static_cast<GLenum>(GL_TEXTURE0 + i));
texture->bind(oglContext);
texture->setupTextureParamsFromSampler(oglContext, *sampler);
CVF_CHECK_OGL(oglContext);
}
}
//--------------------------------------------------------------------------------------------------
/// Specify the mapping between the sampler name in the shader program and the texture unit
/// This is done by providing an Int Uniform with the name of the sampler and the index of the
/// texture unit.
//--------------------------------------------------------------------------------------------------
void RenderStateTextureBindings::applySamplerTextureUnitUniforms(OpenGLContext* oglContext, ShaderProgram* shaderProgram) const
{
CVF_ASSERT(shaderProgram);
int i;
for (i = 0; i < m_bindingCount; i++)
{
UniformInt uniform(m_bindings[i].samplerUniformName.toAscii().ptr(), i);
shaderProgram->applyUniform(oglContext, uniform);
}
}
} // namespace cvf

View File

@ -0,0 +1,73 @@
//##################################################################################################
//
// Custom Visualization Core library
// Copyright (C) 2011-2012 Ceetron AS
//
// 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.
//
//##################################################################################################
#pragma once
#include "cvfRenderState.h"
#include "cvfString.h"
namespace cvf {
class Sampler;
class Texture;
class ShaderProgram;
//==================================================================================================
//
// Binds a texture and a sampler to a texture unit
//
//==================================================================================================
class RenderStateTextureBindings : public RenderState
{
public:
RenderStateTextureBindings();
RenderStateTextureBindings(Texture* texture, Sampler* sampler, const char* samplerUniformName);
~RenderStateTextureBindings();
void addBinding(Texture* texture, Sampler* sampler, const char* samplerUniformName);
int bindingCount() const;
Texture* texture(int bindingIdx);
const Texture* texture(int bindingIdx) const;
Sampler* sampler(int bindingIdx);
const Sampler* sampler(int bindingIdx) const;
String samplerUniformName(int bindingIdx) const;
virtual void applyOpenGL(OpenGLContext* oglContext) const;
void setupTextures(OpenGLContext* oglContext);
void applySamplerTextureUnitUniforms(OpenGLContext* oglContext, ShaderProgram* shaderProgram) const;
public:
static const int MAX_TEXTURE_UNITS = 16;
private:
struct BindingEntry
{
ref<Texture> texture;
ref<Sampler> sampler;
String samplerUniformName;
};
BindingEntry m_bindings[MAX_TEXTURE_UNITS];
int m_bindingCount;
};
} // namespace cvf

View File

@ -20,6 +20,17 @@
#include "cvfBase.h"
#include "cvfRenderStateTracker.h"
#include "cvfRenderStateSet.h"
#include "cvfRenderStateBlending.h"
#include "cvfRenderStateColorMask.h"
#include "cvfRenderStateCullFace.h"
#include "cvfRenderStateDepth.h"
#include "cvfRenderStateFrontFace.h"
#include "cvfRenderStateLine.h"
#include "cvfRenderStatePoint.h"
#include "cvfRenderStatePolygonMode.h"
#include "cvfRenderStatePolygonOffset.h"
#include "cvfRenderStateStencil.h"
#include "cvfRenderStateTextureBindings.h"
#include "cvfOpenGLContext.h"
#include "cvfOpenGLCapabilities.h"
@ -59,21 +70,23 @@ RenderStateTracker::RenderStateTracker()
//--------------------------------------------------------------------------------------------------
void RenderStateTracker::setupDefaultRenderStates()
{
m_defaultRenderStates[RenderState::BLENDING] = new Blending;
m_defaultRenderStates[RenderState::COLOR_MASK] = new ColorMask;
m_defaultRenderStates[RenderState::CULL_FACE] = new CullFace(false);
m_defaultRenderStates[RenderState::FRONT_FACE] = new FrontFace;
m_defaultRenderStates[RenderState::DEPTH] = new Depth;
m_defaultRenderStates[RenderState::POINT] = new Point;
m_defaultRenderStates[RenderState::POLYGON_MODE] = new PolygonMode;
m_defaultRenderStates[RenderState::POLYGON_OFFSET] = new PolygonOffset;
m_defaultRenderStates[RenderState::TEXTURE_BINDINGS] = new TextureBindings;
m_defaultRenderStates[RenderState::BLENDING] = new RenderStateBlending;
m_defaultRenderStates[RenderState::COLOR_MASK] = new RenderStateColorMask;
m_defaultRenderStates[RenderState::CULL_FACE] = new RenderStateCullFace(false);
m_defaultRenderStates[RenderState::DEPTH] = new RenderStateDepth;
m_defaultRenderStates[RenderState::FRONT_FACE] = new RenderStateFrontFace;
m_defaultRenderStates[RenderState::LINE] = new RenderStateLine;
m_defaultRenderStates[RenderState::POINT] = new RenderStatePoint;
m_defaultRenderStates[RenderState::POLYGON_MODE] = new RenderStatePolygonMode;
m_defaultRenderStates[RenderState::POLYGON_OFFSET] = new RenderStatePolygonOffset;
m_defaultRenderStates[RenderState::STENCIL] = new RenderStateStencil;
m_defaultRenderStates[RenderState::TEXTURE_BINDINGS] = new RenderStateTextureBindings;
#ifndef CVF_OPENGL_ES
m_defaultRenderStates[RenderState::LIGHTING_FF] = new Lighting_FF;
m_defaultRenderStates[RenderState::MATERIAL_FF] = new Material_FF;
m_defaultRenderStates[RenderState::NORMALIZE_FF] = new Normalize_FF(false);
m_defaultRenderStates[RenderState::TEXTURE_MAPPING_FF] = new TextureMapping_FF;
m_defaultRenderStates[RenderState::LIGHTING_FF] = new RenderStateLighting_FF;
m_defaultRenderStates[RenderState::MATERIAL_FF] = new RenderStateMaterial_FF;
m_defaultRenderStates[RenderState::NORMALIZE_FF] = new RenderStateNormalize_FF(false);
m_defaultRenderStates[RenderState::TEXTURE_MAPPING_FF] = new RenderStateTextureMapping_FF;
#endif
}

View File

@ -31,7 +31,7 @@ namespace cvf {
//==================================================================================================
///
/// \class cvf::Lighting_FF
/// \class cvf::RenderStateLighting_FF
/// \ingroup Render
///
/// Encapsulate OpenGL glLightModel() and glEnable()/glDisable() with GL_LIGHTING
@ -43,7 +43,7 @@ namespace cvf {
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Lighting_FF::Lighting_FF(bool enableLighting)
RenderStateLighting_FF::RenderStateLighting_FF(bool enableLighting)
: RenderState(LIGHTING_FF),
m_enableLighting(enableLighting),
m_twoSided(false),
@ -58,7 +58,7 @@ Lighting_FF::Lighting_FF(bool enableLighting)
///
/// \sa http://www.opengl.org/sdk/docs/man/xhtml/glEnable.xml with GL_LIGHTING
//--------------------------------------------------------------------------------------------------
void Lighting_FF::enable(bool enableLighting)
void RenderStateLighting_FF::enable(bool enableLighting)
{
m_enableLighting = enableLighting;
}
@ -67,7 +67,7 @@ void Lighting_FF::enable(bool enableLighting)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Lighting_FF::enableTwoSided(bool enableTwoSided)
void RenderStateLighting_FF::enableTwoSided(bool enableTwoSided)
{
m_twoSided = enableTwoSided;
}
@ -76,7 +76,7 @@ void Lighting_FF::enableTwoSided(bool enableTwoSided)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Lighting_FF::enableLocalViewer(bool enableLocalViewer)
void RenderStateLighting_FF::enableLocalViewer(bool enableLocalViewer)
{
m_localViewer = enableLocalViewer;
}
@ -85,7 +85,7 @@ void Lighting_FF::enableLocalViewer(bool enableLocalViewer)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Lighting_FF::setAmbientIntensity(const Color3f& ambientIntensity)
void RenderStateLighting_FF::setAmbientIntensity(const Color3f& ambientIntensity)
{
m_ambientIntensity.set(ambientIntensity, 1.0f);
}
@ -94,7 +94,7 @@ void Lighting_FF::setAmbientIntensity(const Color3f& ambientIntensity)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Lighting_FF::isEnabled() const
bool RenderStateLighting_FF::isEnabled() const
{
return m_enableLighting;
}
@ -103,7 +103,7 @@ bool Lighting_FF::isEnabled() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Lighting_FF::isTwoSidedEnabled() const
bool RenderStateLighting_FF::isTwoSidedEnabled() const
{
return m_twoSided;
}
@ -112,7 +112,7 @@ bool Lighting_FF::isTwoSidedEnabled() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Lighting_FF::isLocalViewerEnabled() const
bool RenderStateLighting_FF::isLocalViewerEnabled() const
{
return m_localViewer;
}
@ -121,7 +121,7 @@ bool Lighting_FF::isLocalViewerEnabled() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color3f Lighting_FF::ambientIntensity() const
Color3f RenderStateLighting_FF::ambientIntensity() const
{
return m_ambientIntensity.toColor3f();
}
@ -130,7 +130,7 @@ Color3f Lighting_FF::ambientIntensity() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Lighting_FF::applyOpenGL(OpenGLContext* oglContext) const
void RenderStateLighting_FF::applyOpenGL(OpenGLContext* oglContext) const
{
if (m_enableLighting)
{
@ -154,7 +154,7 @@ void Lighting_FF::applyOpenGL(OpenGLContext* oglContext) const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Lighting_FF::isFixedFunction() const
bool RenderStateLighting_FF::isFixedFunction() const
{
return true;
}
@ -163,7 +163,7 @@ bool Lighting_FF::isFixedFunction() const
//==================================================================================================
///
/// \class cvf::Material_FF
/// \class cvf::RenderStateMaterial_FF
/// \ingroup Render
///
///
@ -173,7 +173,7 @@ bool Lighting_FF::isFixedFunction() const
//--------------------------------------------------------------------------------------------------
/// Default constructor, initializes all values to OpenGL defaults
//--------------------------------------------------------------------------------------------------
Material_FF::Material_FF()
RenderStateMaterial_FF::RenderStateMaterial_FF()
: RenderState(MATERIAL_FF),
m_ambient(0.2f, 0.2f, 0.2f),
m_diffuse(0.8f, 0.8f, 0.8f),
@ -189,7 +189,7 @@ Material_FF::Material_FF()
//--------------------------------------------------------------------------------------------------
/// Constructor taking ambient and diffuse color
//--------------------------------------------------------------------------------------------------
Material_FF::Material_FF(const Color3f& ambientAndDiffuseColor)
RenderStateMaterial_FF::RenderStateMaterial_FF(const Color3f& ambientAndDiffuseColor)
: RenderState(MATERIAL_FF),
m_ambient(ambientAndDiffuseColor),
m_diffuse(ambientAndDiffuseColor),
@ -205,7 +205,7 @@ Material_FF::Material_FF(const Color3f& ambientAndDiffuseColor)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Material_FF::Material_FF(MaterialIdent materialIdent)
RenderStateMaterial_FF::RenderStateMaterial_FF(MaterialIdent materialIdent)
: RenderState(MATERIAL_FF),
m_specular(0, 0, 0),
m_emission(0, 0, 0),
@ -263,7 +263,7 @@ Material_FF::Material_FF(MaterialIdent materialIdent)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Material_FF::setAmbientAndDiffuse(const Color3f& color)
void RenderStateMaterial_FF::setAmbientAndDiffuse(const Color3f& color)
{
CVF_ASSERT(color.isValid());
@ -274,7 +274,7 @@ void Material_FF::setAmbientAndDiffuse(const Color3f& color)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Material_FF::setDiffuse(const Color3f& color)
void RenderStateMaterial_FF::setDiffuse(const Color3f& color)
{
CVF_ASSERT(color.isValid());
@ -285,7 +285,7 @@ void Material_FF::setDiffuse(const Color3f& color)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Material_FF::setSpecular(const Color3f& color)
void RenderStateMaterial_FF::setSpecular(const Color3f& color)
{
CVF_ASSERT(color.isValid());
@ -296,7 +296,18 @@ void Material_FF::setSpecular(const Color3f& color)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Material_FF::setAlpha(float alpha)
void RenderStateMaterial_FF::setEmission(const Color3f& color)
{
CVF_ASSERT(color.isValid());
m_emission = color;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void RenderStateMaterial_FF::setAlpha(float alpha)
{
m_alpha = alpha;
}
@ -307,7 +318,7 @@ void Material_FF::setAlpha(float alpha)
/// Only values in the range 0 128 are accepted. The initial specular exponent for
/// both front- and back-facing materials is 0
//--------------------------------------------------------------------------------------------------
void Material_FF::setShininess(float shininess)
void RenderStateMaterial_FF::setShininess(float shininess)
{
m_shininess = shininess;
}
@ -316,7 +327,7 @@ void Material_FF::setShininess(float shininess)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color3f Material_FF::frontAmbient() const
Color3f RenderStateMaterial_FF::frontAmbient() const
{
return m_ambient;
}
@ -325,7 +336,7 @@ Color3f Material_FF::frontAmbient() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color3f Material_FF::frontDiffuse() const
Color3f RenderStateMaterial_FF::frontDiffuse() const
{
return m_diffuse;
}
@ -334,7 +345,7 @@ Color3f Material_FF::frontDiffuse() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color3f Material_FF::frontSpecular() const
Color3f RenderStateMaterial_FF::frontSpecular() const
{
return m_specular;
}
@ -343,7 +354,7 @@ Color3f Material_FF::frontSpecular() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color3f Material_FF::frontEmission() const
Color3f RenderStateMaterial_FF::frontEmission() const
{
return m_emission;
}
@ -352,7 +363,7 @@ Color3f Material_FF::frontEmission() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float Material_FF::frontAlpha() const
float RenderStateMaterial_FF::frontAlpha() const
{
return m_alpha;
}
@ -361,7 +372,7 @@ float Material_FF::frontAlpha() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
float Material_FF::frontShininess() const
float RenderStateMaterial_FF::frontShininess() const
{
return m_shininess;
}
@ -370,7 +381,7 @@ float Material_FF::frontShininess() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Material_FF::enableColorMaterial(bool enableColorMaterial)
void RenderStateMaterial_FF::enableColorMaterial(bool enableColorMaterial)
{
m_enableColorMaterial = enableColorMaterial;
}
@ -379,7 +390,7 @@ void Material_FF::enableColorMaterial(bool enableColorMaterial)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Material_FF::isColorMaterialEnabled() const
bool RenderStateMaterial_FF::isColorMaterialEnabled() const
{
return m_enableColorMaterial;
}
@ -388,7 +399,7 @@ bool Material_FF::isColorMaterialEnabled() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Material_FF::applyOpenGL(OpenGLContext* oglContext) const
void RenderStateMaterial_FF::applyOpenGL(OpenGLContext* oglContext) const
{
Color4f ambient(m_ambient, m_alpha);
Color4f diffuse(m_diffuse, m_alpha);
@ -427,7 +438,7 @@ void Material_FF::applyOpenGL(OpenGLContext* oglContext) const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Material_FF::isFixedFunction() const
bool RenderStateMaterial_FF::isFixedFunction() const
{
return true;
}
@ -437,7 +448,7 @@ bool Material_FF::isFixedFunction() const
//==================================================================================================
///
/// \class cvf::Normalize_FF
/// \class cvf::RenderStateNormalize_FF
/// \ingroup Render
///
/// Controls normalization of normals in fixed function
@ -447,7 +458,7 @@ bool Material_FF::isFixedFunction() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Normalize_FF::Normalize_FF(bool enableNormalization)
RenderStateNormalize_FF::RenderStateNormalize_FF(bool enableNormalization)
: RenderState(NORMALIZE_FF),
m_enable(enableNormalization)
{
@ -457,7 +468,7 @@ Normalize_FF::Normalize_FF(bool enableNormalization)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Normalize_FF::enable(bool enableNormalization)
void RenderStateNormalize_FF::enable(bool enableNormalization)
{
m_enable = enableNormalization;
}
@ -466,7 +477,7 @@ void Normalize_FF::enable(bool enableNormalization)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool Normalize_FF::isEnabled() const
bool RenderStateNormalize_FF::isEnabled() const
{
return m_enable;
}
@ -475,7 +486,7 @@ bool Normalize_FF::isEnabled() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void Normalize_FF::applyOpenGL(OpenGLContext* oglContext) const
void RenderStateNormalize_FF::applyOpenGL(OpenGLContext* oglContext) const
{
if (m_enable)
{
@ -493,7 +504,7 @@ void Normalize_FF::applyOpenGL(OpenGLContext* oglContext) const
//==================================================================================================
///
/// \class cvf::TextureMapping_FF
/// \class cvf::RenderStateTextureMapping_FF
/// \ingroup Render
///
/// Enable 2D texturing for texture unit 0 and fixed function
@ -503,7 +514,7 @@ void Normalize_FF::applyOpenGL(OpenGLContext* oglContext) const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TextureMapping_FF::TextureMapping_FF(Texture2D_FF* texture)
RenderStateTextureMapping_FF::RenderStateTextureMapping_FF(Texture2D_FF* texture)
: RenderState(TEXTURE_MAPPING_FF),
m_texture(texture),
m_textureFunction(MODULATE),
@ -515,7 +526,7 @@ TextureMapping_FF::TextureMapping_FF(Texture2D_FF* texture)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TextureMapping_FF::~TextureMapping_FF()
RenderStateTextureMapping_FF::~RenderStateTextureMapping_FF()
{
}
@ -523,7 +534,7 @@ TextureMapping_FF::~TextureMapping_FF()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void TextureMapping_FF::setTexture(Texture2D_FF* texture)
void RenderStateTextureMapping_FF::setTexture(Texture2D_FF* texture)
{
m_texture = texture;
}
@ -532,7 +543,7 @@ void TextureMapping_FF::setTexture(Texture2D_FF* texture)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Texture2D_FF* TextureMapping_FF::texture()
Texture2D_FF* RenderStateTextureMapping_FF::texture()
{
return m_texture.p();
}
@ -541,7 +552,7 @@ Texture2D_FF* TextureMapping_FF::texture()
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void TextureMapping_FF::setTextureFunction(TextureFunction texFunc)
void RenderStateTextureMapping_FF::setTextureFunction(TextureFunction texFunc)
{
m_textureFunction = texFunc;
}
@ -550,7 +561,7 @@ void TextureMapping_FF::setTextureFunction(TextureFunction texFunc)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
TextureMapping_FF::TextureFunction TextureMapping_FF::textureFunction() const
RenderStateTextureMapping_FF::TextureFunction RenderStateTextureMapping_FF::textureFunction() const
{
return m_textureFunction;
}
@ -559,7 +570,7 @@ TextureMapping_FF::TextureFunction TextureMapping_FF::textureFunction() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void TextureMapping_FF::setEnvironmentMapping(bool environmentMapping)
void RenderStateTextureMapping_FF::setEnvironmentMapping(bool environmentMapping)
{
m_environmentMapping = environmentMapping;
}
@ -568,7 +579,7 @@ void TextureMapping_FF::setEnvironmentMapping(bool environmentMapping)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool TextureMapping_FF::environmentMapping() const
bool RenderStateTextureMapping_FF::environmentMapping() const
{
return m_environmentMapping;
}
@ -577,7 +588,7 @@ bool TextureMapping_FF::environmentMapping() const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void TextureMapping_FF::setupTexture(OpenGLContext* oglContext)
void RenderStateTextureMapping_FF::setupTexture(OpenGLContext* oglContext)
{
CVF_CALLSITE_OPENGL(oglContext);
@ -601,7 +612,7 @@ void TextureMapping_FF::setupTexture(OpenGLContext* oglContext)
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void TextureMapping_FF::applyOpenGL(OpenGLContext* oglContext) const
void RenderStateTextureMapping_FF::applyOpenGL(OpenGLContext* oglContext) const
{
CVF_CALLSITE_OPENGL(oglContext);
@ -656,7 +667,7 @@ void TextureMapping_FF::applyOpenGL(OpenGLContext* oglContext) const
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool TextureMapping_FF::isFixedFunction() const
bool RenderStateTextureMapping_FF::isFixedFunction() const
{
return true;
}

View File

@ -32,10 +32,10 @@ class Texture2D_FF;
// Encapsulates OpenGL's glLightModel() and glEnable()/glDisable() with GL_LIGHTING
//
//==================================================================================================
class Lighting_FF : public RenderState
class RenderStateLighting_FF : public RenderState
{
public:
Lighting_FF(bool enableLighting = true);
RenderStateLighting_FF(bool enableLighting = true);
void enable(bool enableLighting);
bool isEnabled() const;
@ -65,7 +65,7 @@ private:
// Encapsulates OpenGL glMaterial() state
//
//==================================================================================================
class Material_FF : public RenderState
class RenderStateMaterial_FF : public RenderState
{
public:
enum MaterialIdent
@ -114,13 +114,14 @@ public:
};
public:
Material_FF();
explicit Material_FF(const Color3f& ambientAndDiffuseColor);
explicit Material_FF(MaterialIdent materialIdent);
RenderStateMaterial_FF();
explicit RenderStateMaterial_FF(const Color3f& ambientAndDiffuseColor);
explicit RenderStateMaterial_FF(MaterialIdent materialIdent);
void setAmbientAndDiffuse(const Color3f& color);
void setDiffuse(const Color3f& color);
void setSpecular(const Color3f& color);
void setEmission(const Color3f& color);
void setAlpha(float alpha);
void setShininess(float shininess);
@ -153,10 +154,10 @@ private:
// Controls normalization of normals in fixed function
//
//==================================================================================================
class Normalize_FF : public RenderState
class RenderStateNormalize_FF : public RenderState
{
public:
Normalize_FF(bool enableNormalization = true);
RenderStateNormalize_FF(bool enableNormalization = true);
void enable(bool enableNormalization);
bool isEnabled() const;
@ -173,7 +174,7 @@ private:
//
//
//==================================================================================================
class TextureMapping_FF : public RenderState
class RenderStateTextureMapping_FF : public RenderState
{
public:
enum TextureFunction
@ -183,8 +184,8 @@ public:
};
public:
TextureMapping_FF(Texture2D_FF* texture = NULL);
~TextureMapping_FF();
RenderStateTextureMapping_FF(Texture2D_FF* texture = NULL);
~RenderStateTextureMapping_FF();
void setTexture(Texture2D_FF* texture);
Texture2D_FF* texture();

View File

@ -78,7 +78,7 @@ void Sampler::setWrapModeT(WrapMode wrapMode)
//--------------------------------------------------------------------------------------------------
///
/// Set the texture minifying filter function
//--------------------------------------------------------------------------------------------------
void Sampler::setMinFilter(Filter minFilter)
{
@ -87,7 +87,9 @@ void Sampler::setMinFilter(Filter minFilter)
//--------------------------------------------------------------------------------------------------
/// Set the magnification filter function
///
/// \param magFilter Filter function to use. Legal values are NEAREST and LINEAR.
//--------------------------------------------------------------------------------------------------
void Sampler::setMagFilter(Filter magFilter)
{

View File

@ -44,7 +44,7 @@ class Sampler : public Object
public:
enum WrapMode
{
REPEAT, // OpenGL default
REPEAT, // OpenGL default
CLAMP_TO_EDGE,
CLAMP_TO_BORDER,
MIRRORED_REPEAT
@ -52,12 +52,12 @@ public:
enum Filter
{
NEAREST,
LINEAR, // Default mag filter in OpenGL
NEAREST_MIPMAP_NEAREST,
LINEAR_MIPMAP_NEAREST,
NEAREST_MIPMAP_LINEAR, // Default min filter in OpenGL
LINEAR_MIPMAP_LINEAR
NEAREST, ///< Nearest neighbor filtering on the base mip level
LINEAR, ///< Linear filtering on the base mip level. (Default magnification filter in OpenGL)
NEAREST_MIPMAP_NEAREST, ///< Selects nearest mip level and performs nearest neighbor filtering
LINEAR_MIPMAP_NEAREST, ///< Selects nearest mip level and performs linear filtering
NEAREST_MIPMAP_LINEAR, ///< Perform linear interpolation between mip levels and perform nearest neighbor filtering. (Default minifying filter in OpenGL)
LINEAR_MIPMAP_LINEAR ///< Perform linear interpolation between mip levels and perform linear filtering (trilinear mipmapping)
};
public:
@ -75,10 +75,10 @@ public:
Filter magFilter() const;
private:
WrapMode m_wrapModeS;
WrapMode m_wrapModeT;
Filter m_minFilter;
Filter m_magFilter;
WrapMode m_wrapModeS; ///< Wrap mode for texture coordinate S. Default is REPEAT
WrapMode m_wrapModeT; ///< Wrap mode for texture coordinate T. Default is REPEAT
Filter m_minFilter; ///< Minifying function. Default is NEAREST_MIPMAP_LINEAR
Filter m_magFilter; ///< Magnification function. Default is LINEAR
};
} // namespace cvf

View File

@ -33,6 +33,9 @@ namespace cvf {
///
//==================================================================================================
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
@ -139,8 +142,8 @@ ref<Color3ubArray> ScalarMapper::colorTableArray(ColorTable colorTable)
case NORMAL:
{
// Choses the primary colors only variant
colors = normalColorTableArray(5);
// Which number of levels should we choose here?
colors = normalColorTableArray(10);
break;
}
}

View File

@ -19,8 +19,10 @@
#pragma once
#include "cvfBase.h"
#include "cvfObject.h"
#include "cvfArray.h"
#include <vector>
namespace cvf {
@ -30,6 +32,8 @@ class TextureImage;
//==================================================================================================
//
// Abstract base class for mapping scalar values to texture coordinates/colors
// It also provides an interface that OverlayScalarMapperLegend's use to draw consistent colors
// and labels/ticks
//
//==================================================================================================
class ScalarMapper : public Object
@ -51,15 +55,34 @@ public:
};
public:
virtual Vec2f mapToTextureCoord(double scalarValue) const = 0;
virtual Color3ub mapToColor(double scalarValue) const = 0;
//////
// Interface for mapping of scalar values to color and texture
virtual bool updateTexture(TextureImage* image) const = 0;
/// Calculate texture coords into an image produced by updateTexture, from the scalarValue
virtual Vec2f mapToTextureCoord(double scalarValue) const = 0;
/// Update the supplied TextureImage to be addressable by the texture coords delivered by mapToTextureCoord
virtual bool updateTexture(TextureImage* image) const = 0;
/// Calculate a color from the scalar value
virtual Color3ub mapToColor(double scalarValue) const = 0;
//////
// Interface used by OverlayScalarMapperLegend:
/// Return a the set of domain values representing sensible major tickmarks
virtual void majorTickValues(std::vector<double>* domainValues) const = 0;
/// Return the normalized (0.0, 1.0) representation of the domainValue
virtual double normalizedValue(double domainValue) const = 0;
/// Return the domain value from a normalized val
virtual double domainValue(double normalizedValue) const = 0;
protected:
static ref<Color3ubArray> colorTableArray(ColorTable colorTable);
static ref<Color3ubArray> normalColorTableArray(uint colorCount);
static ref<Color3ubArray> interpolateColorArray(const Color3ubArray& colorArray, uint targetColorCount);
// Static utility methods that can be used when creating real ScalarMapper's
static ref<Color3ubArray> colorTableArray(ColorTable colorTable);
static ref<Color3ubArray> normalColorTableArray(uint colorCount);
static ref<Color3ubArray> interpolateColorArray(const Color3ubArray& colorArray, uint targetColorCount);
};

View File

@ -35,7 +35,7 @@ namespace cvf {
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double ScalarMapperContinuousLinear::normalizedLevelPosition(double domainValue) const
double ScalarMapperContinuousLinear::normalizedValue(double domainValue) const
{
double range = m_rangeMax - m_rangeMin;
if (range != 0) return cvf::Math::clamp((domainValue - m_rangeMin)/range, 0.0, 1.0);

View File

@ -19,11 +19,9 @@
#pragma once
#include "cvfScalarMapperContinuousLog.h"
#include "cvfScalarMapperRangeBased.h"
namespace cvf
{
namespace cvf {
//==================================================================================================
//
@ -31,12 +29,14 @@ namespace cvf
//
//==================================================================================================
class ScalarMapperContinuousLinear : public ScalarMapperContinuousLog
class ScalarMapperContinuousLinear : public ScalarMapperRangeBased
{
public:
ScalarMapperContinuousLinear() {m_decadeLevelCount = 2; }
protected:
virtual double normalizedLevelPosition( double domainValue ) const;
// Implementing the Scalarmapper interface
virtual double normalizedValue( double domainValue ) const;
virtual double domainValue( double normalizedPosition ) const;
};

View File

@ -34,173 +34,14 @@ namespace cvf {
/// Configured by specifying a number of level colors and a min/max range.
//==================================================================================================
ScalarMapperContinuousLog::ScalarMapperContinuousLog()
: m_rangeMin(1),
m_rangeMax(1),
m_decadeLevelCount(1),
m_majorLevelCount(8),
m_textureSize(2048) // Large enough, I guess and a power of two
{
m_colors.resize(m_textureSize);
m_colors.setAll(Color3ub::WHITE);
setColors(ScalarMapper::NORMAL);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ScalarMapperContinuousLog::setRange(double min, double max)
{
m_rangeMin = min;
m_rangeMax = max;
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ScalarMapperContinuousLog::setColors(const Color3ubArray& colorArray)
{
m_colors = *interpolateColorArray(colorArray, m_textureSize);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ScalarMapperContinuousLog::setColors(ColorTable colorTable)
{
ref<Color3ubArray> baseColors = colorTableArray(colorTable);
setColors(*baseColors);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Vec2f ScalarMapperContinuousLog::mapToTextureCoord(double scalarValue) const
{
return Vec2f(static_cast<float>(normalizedLevelPosition(scalarValue)), 0.5f);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
Color3ub ScalarMapperContinuousLog::mapToColor(double scalarValue) const
{
size_t colorIdx = static_cast<size_t>(normalizedLevelPosition(scalarValue) * (m_textureSize - 1));
CVF_TIGHT_ASSERT(colorIdx < m_colors.size());
return m_colors[colorIdx];
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
bool ScalarMapperContinuousLog::updateTexture(TextureImage* image) const
{
CVF_ASSERT(image);
image->allocate(m_textureSize, 1);
// For now fill with white so we can see any errors more easily
image->fill(Color4ub(Color3::WHITE));
uint ic;
for (ic = 0; ic < m_textureSize; ic++)
{
const Color4ub clr(m_colors[ic], 255);
image->setPixel(ic, 0, clr);
}
return true;
}
// Then calculate a stepsize that is humanly understandable
// basically rounded to whole or half of the decade in question
static double adjust(double domainValue, double decadeValue, unsigned int decadeParts = 2)
{
if (decadeValue == 0) return domainValue; // Conceptually correct
//double sign = domainValue >= 0 ? 1.0 : -1.0;
// Calculate the decade
decadeValue = cvf::Math::abs(decadeValue);
double logDecValue = log10(decadeValue );
logDecValue = cvf::Math::floor(logDecValue);
double decade = pow(10.0, logDecValue);
double firstDecadeDomVal = decadeParts*domainValue/decade;
double roundedFirstDecadeDomVal;
if ( cvf::Math::abs(firstDecadeDomVal - cvf::Math::floor(firstDecadeDomVal)) < cvf::Math::abs(ceil(firstDecadeDomVal) - firstDecadeDomVal))
{
roundedFirstDecadeDomVal = cvf::Math::floor(firstDecadeDomVal);
}
else
{
roundedFirstDecadeDomVal = ceil(firstDecadeDomVal);
}
double newStep = decade*(roundedFirstDecadeDomVal)/decadeParts;
return newStep;
}
//--------------------------------------------------------------------------------------------------
/// Calculates a set of humanly readable levels. Works very well for linear, and ok for logarithmic.
/// The logarithmic needs a bit more tweaking, so should override this method for linear but not yet done.
//--------------------------------------------------------------------------------------------------
void ScalarMapperContinuousLog::majorLevels( std::vector<double>* domainValues) const
{
CVF_ASSERT(domainValues != NULL);
domainValues->push_back(m_rangeMin);
if (m_majorLevelCount > 1)
{
double stepSizeNorm = 1.0/m_majorLevelCount;
size_t i;
if (m_adjustLevels) // adjust levels
{
double prevDomValue = domainValue(0);
for (i = 1; i < m_majorLevelCount + 5; ++i)
{
double prevNormPos = normalizedLevelPosition(prevDomValue);
double newNormPos = prevNormPos + stepSizeNorm;
double domValue = domainValue(newNormPos);
double domStep = domValue - prevDomValue;
double newLevel;
newLevel = prevDomValue + adjust(domStep, domStep, m_decadeLevelCount);
// Must handle first level specially to get a good absolute staring point
// For log domain this must be done all the time, and it does not hamper linear, so.. do it always
newLevel = adjust(newLevel, domStep, m_decadeLevelCount);
if (newLevel > m_rangeMax - domStep*0.4) break;
domainValues->push_back(newLevel);
prevDomValue = newLevel;
}
}
else
{
for (i = 1; i < m_majorLevelCount; ++i)
{
domainValues->push_back(domainValue(stepSizeNorm*i));
}
}
}
domainValues->push_back(m_rangeMax);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
double ScalarMapperContinuousLog::normalizedLevelPosition(double scalarValue) const
double ScalarMapperContinuousLog::normalizedValue(double scalarValue) const
{
double logRangeMax = log10(m_rangeMax);
double logRangeMin = log10(m_rangeMin);
@ -234,13 +75,4 @@ double ScalarMapperContinuousLog::domainValue(double normalizedPosition) const
return pow(10, logValue);
}
//--------------------------------------------------------------------------------------------------
///
//--------------------------------------------------------------------------------------------------
void ScalarMapperContinuousLog::setMajorLevelCount(size_t levelCount, bool adjustLevels)
{
m_majorLevelCount = levelCount;
m_adjustLevels = adjustLevels;
}
} // namespace cvf

Some files were not shown because too many files have changed in this diff Show More