///////////////////////////////////////////////////////////////////////////////// // // Copyright (C) Statoil ASA // Copyright (C) Ceetron Solutions AS // // ResInsight 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. // // ResInsight 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 // for more details. // ///////////////////////////////////////////////////////////////////////////////// #include "cvfBase.h" #include "RivTernarySaturationOverlayItem.h" #include "cvfOpenGL.h" #include "cvfViewport.h" #include "cvfCamera.h" #include "cvfTextDrawer.h" #include "cvfFont.h" #include "cvfMatrixState.h" #include "cvfRenderState_FF.h" #include "cvfRenderStateDepth.h" #include "cvfRenderStatePolygonOffset.h" //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RivTernarySaturationOverlayItem::RivTernarySaturationOverlayItem(cvf::Font* font) : m_textColor(cvf::Color3::BLACK), m_font(font), m_size(100, 140) { } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- RivTernarySaturationOverlayItem::~RivTernarySaturationOverlayItem() { // Empty destructor to avoid errors with undefined types when cvf::ref's destructor gets called } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivTernarySaturationOverlayItem::setAxisLabelsColor(const cvf::Color3f& color) { m_textColor = color; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- cvf::Vec2ui RivTernarySaturationOverlayItem::sizeHint() { return m_size; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivTernarySaturationOverlayItem::setSize(const cvf::Vec2ui& size) { m_size = size; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivTernarySaturationOverlayItem::render(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size) { render(oglContext, position, size, false); } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivTernarySaturationOverlayItem::renderSoftware(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size) { render(oglContext, position, size, true); } //-------------------------------------------------------------------------------------------------- /// Set up camera/viewport and render //-------------------------------------------------------------------------------------------------- void RivTernarySaturationOverlayItem::render(cvf::OpenGLContext* oglContext, const cvf::Vec2i& position, const cvf::Vec2ui& size, bool software) { if (size.x() <= 0 || size.y() <= 0) { return; } cvf::Camera camera; camera.setViewport(position.x(), position.y(), size.x(), size.y()); camera.setProjectionAsPixelExact2D(); camera.setViewMatrix(cvf::Mat4d::IDENTITY); camera.applyOpenGL(); camera.viewport()->applyOpenGL(oglContext, cvf::Viewport::CLEAR_DEPTH); cvf::TextDrawer textDrawer(m_font.p()); textDrawer.setTextColor(m_textColor); float lineHeightInPixels = 10; float textPosY = static_cast(size.y() - 10); for (size_t it = 0; it < m_titleStrings.size(); it++) { cvf::Vec2f pos(5, textPosY); textDrawer.addText(m_titleStrings[it], pos); textPosY -= lineHeightInPixels; } cvf::Vec2f pos(5, textPosY); textDrawer.addText("TERNARY", pos); textPosY -= lineHeightInPixels; textPosY -= 2; { cvf::uint sgasTextWidth = m_font->textExtent("SGAS").x(); textDrawer.addText("SGAS", cvf::Vec2f(static_cast( (size.x() / 2) - sgasTextWidth / 2 ), textPosY)); cvf::uint sgasRangeTextWidth = m_font->textExtent(m_sgasRange).x(); textPosY -= lineHeightInPixels; textDrawer.addText(m_sgasRange, cvf::Vec2f(static_cast( (size.x() / 2) - sgasRangeTextWidth / 2 ), textPosY)); } textDrawer.addText("SWAT", cvf::Vec2f(0.0, 10.0)); textDrawer.addText(m_swatRange, cvf::Vec2f(0.0, 0.0)); { cvf::uint soilTextWidth = m_font->textExtent("SOIL").x(); textDrawer.addText("SOIL", cvf::Vec2f(static_cast(size.x() - soilTextWidth), 10.0)); cvf::uint soilRangeTextWidth = m_font->textExtent(m_soilRange).x(); float soilRangePos = static_cast(size.x()) - soilRangeTextWidth; textDrawer.addText(m_soilRange, cvf::Vec2f(soilRangePos, 0.0)); } textDrawer.renderSoftware(oglContext, camera); textPosY -= 3; renderAxisImmediateMode(textPosY, oglContext); CVF_CHECK_OGL(oglContext); } //-------------------------------------------------------------------------------------------------- /// Draw the axis using immediate mode OpenGL //-------------------------------------------------------------------------------------------------- void RivTernarySaturationOverlayItem::renderAxisImmediateMode(float upperBoundY, cvf::OpenGLContext* oglContext) { #ifdef CVF_OPENGL_ES CVF_UNUSED(layout); CVF_FAIL_MSG("Not supported on OpenGL ES"); #else cvf::RenderStateDepth depth(false); depth.applyOpenGL(oglContext); cvf::RenderStateLighting_FF lighting(false); lighting.applyOpenGL(oglContext); cvf::Color3ub colA(cvf::Color3::BLUE); cvf::Color3ub colB(cvf::Color3::GREEN); cvf::Color3ub colC(cvf::Color3::RED); float lowerBoundY = 20; //float upperBoundY = static_cast(m_size.y() - 20); cvf::Vec3f a(0, lowerBoundY, 0); cvf::Vec3f b(static_cast(m_size.x()), lowerBoundY, 0); cvf::Vec3f c(static_cast(m_size.x() / 2), upperBoundY, 0); // Draw filled rectangle elements glBegin(GL_TRIANGLE_FAN); glColor3ubv(colA.ptr()); glVertex3fv(a.ptr()); glColor3ubv(colB.ptr()); glVertex3fv(b.ptr()); glColor3ubv(colC.ptr()); glVertex3fv(c.ptr()); glVertex3fv(c.ptr()); glEnd(); // Lines cvf::Color3ub linesColor(cvf::Color3::WHITE); glColor3ubv(linesColor.ptr()); glBegin(GL_LINE_LOOP); glVertex3fv(a.ptr()); glVertex3fv(b.ptr()); glVertex3fv(c.ptr()); glEnd(); cvf::RenderStateDepth resetDepth; resetDepth.applyOpenGL(oglContext); // Reset render states cvf::RenderStateLighting_FF resetLighting; resetLighting.applyOpenGL(oglContext); CVF_CHECK_OGL(oglContext); #endif // CVF_OPENGL_ES } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivTernarySaturationOverlayItem::setRangeText(const cvf::String& soilRange, const cvf::String& sgasRange, const cvf::String& swatRange) { m_soilRange = soilRange; m_sgasRange = sgasRange; m_swatRange = swatRange; } //-------------------------------------------------------------------------------------------------- /// //-------------------------------------------------------------------------------------------------- void RivTernarySaturationOverlayItem::setTitle(const cvf::String& title) { // Title if (title.isEmpty()) { m_titleStrings.clear(); } else { m_titleStrings = title.split("\n"); } }