From 8e79a781c944a46cdc0b2fe9f2548920e940c98d Mon Sep 17 00:00:00 2001 From: Magne Sjaastad Date: Wed, 14 Sep 2016 08:23:50 +0200 Subject: [PATCH] #827 Fixed issue causing some categories to use uninitialized region of texture --- .../cafVizExtensions/cafCategoryMapper.cpp | 43 ++++++++++++++++++- .../cafVizExtensions/cafCategoryMapper.h | 6 ++- 2 files changed, 46 insertions(+), 3 deletions(-) diff --git a/Fwk/AppFwk/cafVizExtensions/cafCategoryMapper.cpp b/Fwk/AppFwk/cafVizExtensions/cafCategoryMapper.cpp index fb390203ab..8b22153732 100644 --- a/Fwk/AppFwk/cafVizExtensions/cafCategoryMapper.cpp +++ b/Fwk/AppFwk/cafVizExtensions/cafCategoryMapper.cpp @@ -57,6 +57,8 @@ void CategoryMapper::setCycleColors(const Color3ubArray& colorArray) size_t colIdx = i % colorArray.size(); m_colors[i] = colorArray[colIdx]; } + + recomputeMaxTexCoord(); } //-------------------------------------------------------------------------------------------------- @@ -69,6 +71,8 @@ void CategoryMapper::setInterpolateColors(const cvf::Color3ubArray& colorArray) if (m_categoryValues.size() > 1 && colorArray.size() > 1) { m_colors = *interpolateColorArray(colorArray, static_cast(m_categoryValues.size())); + + recomputeMaxTexCoord(); return; } @@ -80,6 +84,8 @@ void CategoryMapper::setInterpolateColors(const cvf::Color3ubArray& colorArray) { m_colors.add(colorArray[0]); } + + recomputeMaxTexCoord(); } //-------------------------------------------------------------------------------------------------- @@ -114,7 +120,17 @@ Vec2f CategoryMapper::mapToTextureCoord(double categoryValue) const { double normVal = normalizedValue(categoryValue); - return Vec2f(static_cast(normVal), 0.5f); + double s = normVal*m_maxTexCoord; + + // Clamp to the currently legal texture coord range + // Might need to add code to correct for float precision, but that is probably not the main enemy. + // Our real problem is the fact that in most cases the texture coords get treated with even less precision + // on the graphics hardware. What we would really like is to guess at the HW precision and then correct for that. + // Currently the workaround is done in updateTexture() which pads the upper end of the texture when we're not filling + // all the texture pixels. + s = Math::clamp(s, 0.0, m_maxTexCoord); + + return Vec2f(static_cast(s), 0.5f); } //-------------------------------------------------------------------------------------------------- @@ -206,6 +222,31 @@ int CategoryMapper::categoryIndexForCategory(double domainValue) const return catIndex; } +//-------------------------------------------------------------------------------------------------- +/// +//-------------------------------------------------------------------------------------------------- +void CategoryMapper::recomputeMaxTexCoord() +{ + const uint numColors = static_cast(m_colors.size()); + if (numColors == 0) + { + m_maxTexCoord = 1.0; + return; + } + + const uint numPixelsPerColor = m_textureSize / numColors; + if (numPixelsPerColor == 0) + { + m_maxTexCoord = 1.0; + return; + } + + uint texturePixelsInUse = numColors*numPixelsPerColor; + CVF_ASSERT(texturePixelsInUse <= m_textureSize); + + m_maxTexCoord = static_cast(texturePixelsInUse) / static_cast(m_textureSize); +} + //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- diff --git a/Fwk/AppFwk/cafVizExtensions/cafCategoryMapper.h b/Fwk/AppFwk/cafVizExtensions/cafCategoryMapper.h index 58a549f491..a4ec3fc1d4 100644 --- a/Fwk/AppFwk/cafVizExtensions/cafCategoryMapper.h +++ b/Fwk/AppFwk/cafVizExtensions/cafCategoryMapper.h @@ -45,10 +45,12 @@ private: const cvf::String textForCategoryIndex(size_t index) const; int categoryIndexForCategory(double domainValue) const; + void recomputeMaxTexCoord(); private: - cvf::Color3ubArray m_colors; - cvf::uint m_textureSize; // The size of texture that updateTexture() is will produce. + cvf::Color3ubArray m_colors; + cvf::uint m_textureSize; // The size of texture that updateTexture() is will produce. + double m_maxTexCoord; // The largest allowable s texture coordinate, scalar values >= m_rangeMax will get mapped to this coordinate std::vector m_categoryValues; std::vector m_categoryNames;