Merge pull request #9 from OPM/internal

Internal
This commit is contained in:
Magne Sjaastad 2012-10-04 05:22:35 -07:00
commit 831d60cb34
166 changed files with 8977 additions and 3232 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

@ -111,11 +111,8 @@ set (CMAKE_INSTALL_PREFIX ${CMAKE_BINARY_DIR}/Install/)
# Application
################################################################################
add_subdirectory(ApplicationCode)
add_subdirectory(OctavePlugin)
# Do not build Octave plugins for Windows 64-bit, as there is no precompiled 64-bit Octave available
if (NOT CMAKE_CL_64)
add_subdirectory(OctavePlugin)
endif()
#
################################################################################

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

@ -17,14 +17,35 @@ endif()
set(OCTAVE_BINARY_OCT_FILES)
# On Windows, the Octave plugins are compiled using 32-bit VS2010
# To be able to do so, we need to establish all Qt-related variables for a 32-bit configuration
# In addition, VS2010 32-bit compile environment must be launched
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows" AND CMAKE_CL_64)
find_program(32BIT_QMAKE 32bitqmake)
if(32BIT_QMAKE)
get_filename_component(32BIT_QMAKE_PATH ${32BIT_QMAKE} PATH) # Get path to 32-bit Qt binary directory
STRING(REPLACE "/bin" "" OCTAVE_QT_ROOT ${32BIT_QMAKE_PATH})
SET(OCTAVE_QT_INCLUDE_DIR ${OCTAVE_QT_ROOT}/include)
SET(OCTAVE_QT_QTCORE_INCLUDE_DIR ${OCTAVE_QT_ROOT}/include/QtCore)
SET(OCTAVE_QT_QTNETWORK_INCLUDE_DIR ${OCTAVE_QT_ROOT}/include/QtNetwork)
SET(OCTAVE_QT_LIBRARY_DIR ${OCTAVE_QT_ROOT}/lib)
endif()
else()
SET(OCTAVE_QT_INCLUDE_DIR ${QT_INCLUDE_DIR})
SET(OCTAVE_QT_QTCORE_INCLUDE_DIR ${QT_QTCORE_INCLUDE_DIR})
SET(OCTAVE_QT_QTNETWORK_INCLUDE_DIR ${QT_QTNETWORK_INCLUDE_DIR})
SET(OCTAVE_QT_LIBRARY_DIR ${QT_LIBRARY_DIR})
endif()
find_program(MKOCTFILE_EXECUTABLE mkoctfile)
if(NOT MKOCTFILE_EXECUTABLE)
message(WARNING "Failed to find mkoctfile")
else()
get_filename_component(OCTAVE_PATH ${MKOCTFILE_EXECUTABLE} PATH)
# Get path to Octave binary directory to be able to build .oct files if Octave is not in path
get_filename_component(OCTAVE_PATH ${MKOCTFILE_EXECUTABLE} PATH)
foreach(srcFileName IN LISTS CPP_SOURCES)
@ -35,22 +56,43 @@ else()
get_filename_component(baseFilename "${srcFileName}" NAME_WE)
set(octFileName "${CMAKE_CURRENT_BINARY_DIR}/${baseFilename}.oct")
if (${CMAKE_SYSTEM_NAME} MATCHES "Windows")
if (CMAKE_CL_64)
# The following line calls the build configuration for x86 VS2010 compiler
# call "\"%VS100COMNTOOLS%../../VC/vcvarsall.bat\"" x86
add_custom_command(
OUTPUT "${octFileName}"
COMMAND call "\"%VS100COMNTOOLS%../../VC/vcvarsall.bat\"" x86
COMMAND ${CMAKE_COMMAND} ARGS -E chdir ${OCTAVE_PATH} ${MKOCTFILE_EXECUTABLE} -I${OCTAVE_QT_QTNETWORK_INCLUDE_DIR}
-I${OCTAVE_QT_QTCORE_INCLUDE_DIR} -I${OCTAVE_QT_INCLUDE_DIR} ${RPATH_COMMAND}
-L${OCTAVE_QT_LIBRARY_DIR} -lQtCore${QT_LIBRARY_POSTFIX} -lQtNetwork${QT_LIBRARY_POSTFIX} -o "${octFileName}" "${srcFileName}"
DEPENDS "${srcFileName}"
COMMENT "Generating ${octFileName}"
)
else()
add_custom_command(
OUTPUT "${octFileName}"
COMMAND ${CMAKE_COMMAND} ARGS -E chdir ${OCTAVE_PATH} ${MKOCTFILE_EXECUTABLE} -I${OCTAVE_QT_QTNETWORK_INCLUDE_DIR}
-I${OCTAVE_QT_QTCORE_INCLUDE_DIR} -I${OCTAVE_QT_INCLUDE_DIR} ${RPATH_COMMAND}
-L${OCTAVE_QT_LIBRARY_DIR} -lQtCore${QT_LIBRARY_POSTFIX} -lQtNetwork${QT_LIBRARY_POSTFIX} -o "${octFileName}" "${srcFileName}"
DEPENDS "${srcFileName}"
COMMENT "Generating ${octFileName}"
)
endif()
else()
add_custom_command(
OUTPUT "${octFileName}"
COMMAND ${MKOCTFILE_EXECUTABLE} -I${QT_QTNETWORK_INCLUDE_DIR} -I${QT_QTCORE_INCLUDE_DIR} -I${QT_INCLUDE_DIR} ${RPATH_COMMAND} -L${QT_LIBRARY_DIR} -lQtCore${QT_LIBRARY_POSTFIX} -lQtNetwork${QT_LIBRARY_POSTFIX} -o "${octFileName}" "${srcFileName}"
DEPENDS "${srcFileName}"
COMMENT "Generating ${octFileName}"
)
endif()
add_custom_command(
OUTPUT "${octFileName}"
COMMAND ${MKOCTFILE_EXECUTABLE} -I${QT_QTNETWORK_INCLUDE_DIR} -I${QT_QTCORE_INCLUDE_DIR} -I${QT_INCLUDE_DIR} ${RPATH_COMMAND} -L${QT_LIBRARY_DIR} -lQtCore${QT_LIBRARY_POSTFIX} -lQtNetwork${QT_LIBRARY_POSTFIX} -o "${octFileName}" "${srcFileName}"
DEPENDS "${srcFileName}"
COMMENT "Generating ${octFileName}"
WORKING_DIRECTORY "${OCTAVE_PATH}"
)
list(APPEND OCTAVE_BINARY_OCT_FILES "${octFileName}")
list(APPEND OCTAVE_BINARY_OCT_FILES "${octFileName}")
endforeach()
#add_custom_target(oct-files ALL DEPENDS "${OCTAVE_BINARY_OCT_FILES}")
add_custom_target(octave_plugins ALL DEPENDS
"${CMAKE_CURRENT_BINARY_DIR}/riGetActiveCellProperty.oct"
"${CMAKE_CURRENT_BINARY_DIR}/riSetActiveCellProperty.oct"

3
README
View File

@ -11,6 +11,9 @@ No efforts to provide documentation has been made yet.
DOWNLOADING RESINSIGHT
git clone git://github.com/OPM/ResInsight.git
CONTRIBUTION
Please use master branch for contributions and pull requests. Please do not use branch 'internal' for contributions.
BUILDING RESINSIGHT
ResInsight uses the cmake build system and requires cmake version 2.8 or higher. Moreover, you need version 4.7.3 of Qt or newer, look below for dependecy list. An out-of-tree build is typically done with
mkdir resinsight-build

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);
};

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