From 842ea9d6ed06cbfc3044387f96582fda2b6316c2 Mon Sep 17 00:00:00 2001 From: Coleman Smith Date: Thu, 10 Dec 2020 21:36:46 +0000 Subject: [PATCH] simplifying a bit - attaching gradient camera directly to the main camera - using Vec4ub --- apps/opencs/model/prefs/state.cpp | 13 ++ apps/opencs/view/render/cellarrow.cpp | 4 +- apps/opencs/view/render/scenewidget.cpp | 154 ++++++++++++++++++++++-- apps/opencs/view/render/scenewidget.hpp | 7 +- 4 files changed, 168 insertions(+), 10 deletions(-) diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 39aae48bda..588be9ccb3 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -210,6 +210,19 @@ void CSMPrefs::State::declare() setTooltip("Size of the orthographic frustum, greater value will allow the camera to see more of the world."). setRange(10, 10000); declareDouble ("object-marker-alpha", "Object Marker Transparency", 0.5).setPrecision(2).setRange(0,1); + declareBool("scene-use-gradient", "Use Gradient Background", true); + declareColour ("scene-day-background-colour", "Day Background Colour", QColor (110, 120, 128, 255)); + declareColour ("scene-day-gradient-colour", "Day Gradient Colour", QColor (47, 51, 51, 255)). + setTooltip("Sets the gradient color to use in conjunction with the day background color. Ignored if " + "the gradient option is disabled."); + declareColour ("scene-bright-background-colour", "Scene Bright Background Colour", QColor (79, 87, 92, 255)); + declareColour ("scene-bright-gradient-colour", "Scene Bright Gradient Colour", QColor (47, 51, 51, 255)). + setTooltip("Sets the gradient color to use in conjunction with the bright background color. Ignored if " + "the gradient option is disabled."); + declareColour ("scene-night-background-colour", "Scene Night Background Colour", QColor (64, 77, 79, 255)); + declareColour ("scene-night-gradient-colour", "Scene Night Gradient Colour", QColor (47, 51, 51, 255)). + setTooltip("Sets the gradient color to use in conjunction with the night background color. Ignored if " + "the gradient option is disabled."); declareCategory ("Tooltips"); declareBool ("scene", "Show Tooltips in 3D scenes", true); diff --git a/apps/opencs/view/render/cellarrow.cpp b/apps/opencs/view/render/cellarrow.cpp index b6fee15459..ac260fe83a 100644 --- a/apps/opencs/view/render/cellarrow.cpp +++ b/apps/opencs/view/render/cellarrow.cpp @@ -151,9 +151,9 @@ void CSVRender::CellArrow::buildShape() osg::Vec4Array *colours = new osg::Vec4Array; for (int i=0; i<6; ++i) - colours->push_back (osg::Vec4f (1.0f, 0.0f, 0.0f, 1.0f)); + colours->push_back (osg::Vec4f (0.11, 0.6f, 0.95f, 1.0f)); for (int i=0; i<6; ++i) - colours->push_back (osg::Vec4f (0.8f, (i==2 || i==5) ? 0.6f : 0.4f, 0.0f, 1.0f)); + colours->push_back (osg::Vec4f (0.08f, 0.44f, 0.7f, 1.0f)); geometry->setColorArray (colours, osg::Array::BIND_PER_VERTEX); diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 3abc01d2e6..b2648da675 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -69,7 +69,6 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f) setLayout(layout); mView->getCamera()->setGraphicsContext(window); - mView->getCamera()->setClearColor( osg::Vec4(0.2, 0.2, 0.6, 1.0) ); mView->getCamera()->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) ); SceneUtil::LightManager* lightMgr = new SceneUtil::LightManager; @@ -212,6 +211,25 @@ SceneWidget::SceneWidget(std::shared_ptr resourceSyste mOrbitCamControl->setConstRoll( CSMPrefs::get()["3D Scene Input"]["navi-orbit-const-roll"].isTrue() ); + // set up gradient view or configured clear color + QColor bgColour = CSMPrefs::get()["Rendering"]["scene-day-background-colour"].toColor(); + + if (CSMPrefs::get()["Rendering"]["scene-use-gradient"].isTrue()) { + QColor gradientColour = CSMPrefs::get()["Rendering"]["scene-day-gradient-colour"].toColor(); + mGradientCamera = createGradientCamera(bgColour, gradientColour); + + mView->getCamera()->setClearMask(0); + mView->getCamera()->addChild(mGradientCamera.get()); + } + else { + mView->getCamera()->setClearColor(osg::Vec4( + bgColour.redF(), + bgColour.greenF(), + bgColour.blueF(), + 1.0f + )); + } + // we handle lighting manually mView->setLightingMode(osgViewer::View::NO_LIGHT); @@ -249,6 +267,81 @@ SceneWidget::~SceneWidget() mResourceSystem->releaseGLObjects(mView->getCamera()->getGraphicsContext()->getState()); } + +osg::ref_ptr SceneWidget::createGradientRectangle(QColor bgColour, QColor gradientColour) +{ + osg::ref_ptr geometry = new osg::Geometry; + + osg::ref_ptr vertices = new osg::Vec3Array; + + vertices->push_back(osg::Vec3(0.0f, 0.0f, -1.0f)); + vertices->push_back(osg::Vec3(1.0f, 0.0f, -1.0f)); + vertices->push_back(osg::Vec3(0.0f, 1.0f, -1.0f)); + vertices->push_back(osg::Vec3(1.0f, 1.0f, -1.0f)); + + geometry->setVertexArray(vertices); + + osg::ref_ptr primitives = new osg::DrawElementsUShort (osg::PrimitiveSet::TRIANGLES, 0); + + // triangle 1 + primitives->push_back (0); + primitives->push_back (1); + primitives->push_back (2); + + // triangle 2 + primitives->push_back (2); + primitives->push_back (1); + primitives->push_back (3); + + geometry->addPrimitiveSet(primitives); + + osg::ref_ptr colours = new osg::Vec4ubArray; + colours->push_back(osg::Vec4ub(gradientColour.red(), gradientColour.green(), gradientColour.blue(), 1.0f)); + colours->push_back(osg::Vec4ub(gradientColour.red(), gradientColour.green(), gradientColour.blue(), 1.0f)); + colours->push_back(osg::Vec4ub(bgColour.red(), bgColour.green(), bgColour.blue(), 1.0f)); + colours->push_back(osg::Vec4ub(bgColour.red(), bgColour.green(), bgColour.blue(), 1.0f)); + + osg::Vec4ub bgVec = osg::Vec4ub(bgColour.red(), bgColour.green(), bgColour.blue(), 1.0f); + + geometry->setColorArray(colours, osg::Array::BIND_PER_VERTEX); + + geometry->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); + geometry->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); + + return geometry; +} + + +osg::ref_ptr SceneWidget::createGradientCamera(QColor bgColour, QColor gradientColour) +{ + osg::ref_ptr camera = new osg::Camera(); + camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); + camera->setProjectionMatrix(osg::Matrix::ortho2D(0, 1.0f, 0, 1.0f)); + camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF); + camera->setViewMatrix(osg::Matrix::identity()); + + camera->setClearMask(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); + camera->setAllowEventFocus(false); + + // draw subgraph before main camera view. + camera->setRenderOrder(osg::Camera::PRE_RENDER); + + camera->getOrCreateStateSet()->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF); + + osg::ref_ptr gradientQuad = createGradientRectangle(bgColour, gradientColour); + + camera->addChild(gradientQuad); + return camera; +} + + +void SceneWidget::updateGradientCamera(QColor bgColour, QColor gradientColour) +{ + osg::ref_ptr gradientRect = createGradientRectangle(bgColour, gradientColour); + // Replaces previous rectangle + mGradientCamera->setChild(0, gradientRect.get()); +} + void SceneWidget::setLighting(Lighting *lighting) { if (mLighting) @@ -276,12 +369,59 @@ void SceneWidget::setAmbient(const osg::Vec4f& ambient) void SceneWidget::selectLightingMode (const std::string& mode) { - if (mode=="day") - setLighting (&mLightingDay); - else if (mode=="night") - setLighting (&mLightingNight); - else if (mode=="bright") - setLighting (&mLightingBright); + QColor backgroundColour; + QColor gradientColour; + if (mode == "day") + { + backgroundColour = CSMPrefs::get()["Rendering"]["scene-day-background-colour"].toColor(); + gradientColour = CSMPrefs::get()["Rendering"]["scene-day-gradient-colour"].toColor(); + setLighting(&mLightingDay); + } + else if (mode == "night") + { + backgroundColour = CSMPrefs::get()["Rendering"]["scene-night-background-colour"].toColor(); + gradientColour = CSMPrefs::get()["Rendering"]["scene-night-gradient-colour"].toColor(); + setLighting(&mLightingNight); + } + else if (mode == "bright") + { + backgroundColour = CSMPrefs::get()["Rendering"]["scene-bright-background-colour"].toColor(); + gradientColour = CSMPrefs::get()["Rendering"]["scene-bright-gradient-colour"].toColor(); + setLighting(&mLightingBright); + } + if (CSMPrefs::get()["Rendering"]["scene-use-gradient"].isTrue()) { + if (mGradientCamera.get() != nullptr) { + // we can go ahead and update since this camera still exists + updateGradientCamera(backgroundColour, gradientColour); + + if (!mView->getCamera()->containsNode(mGradientCamera.get())) + { + // need to re-attach the gradient camera + mView->getCamera()->setClearMask(0); + mView->getCamera()->addChild(mGradientCamera.get()); + } + } + else { + // need to create the gradient camera + mGradientCamera = createGradientCamera(backgroundColour, gradientColour); + mView->getCamera()->setClearMask(0); + mView->getCamera()->addChild(mGradientCamera.get()); + } + } + else { + // Fall back to using the clear color for the camera + mView->getCamera()->setClearMask(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + mView->getCamera()->setClearColor(osg::Vec4( + backgroundColour.redF(), + backgroundColour.greenF(), + backgroundColour.blueF(), + 1.0f + )); + if (mGradientCamera.get() != nullptr && mView->getCamera()->containsNode(mGradientCamera.get())) { + // Remove the child to prevent the gradient from rendering + mView->getCamera()->removeChild(mGradientCamera.get()); + } + } } CSVWidget::SceneToolMode *SceneWidget::makeLightingSelector (CSVWidget::SceneToolbar *parent) diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 6a94254b99..d7d9dba0c5 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -100,10 +100,15 @@ namespace CSVRender void mouseMoveEvent (QMouseEvent *event) override; void wheelEvent (QWheelEvent *event) override; + osg::ref_ptr createGradientRectangle(QColor bgColour, QColor gradientColour); + osg::ref_ptr createGradientCamera(QColor bgColour, QColor gradientColour); + void updateGradientCamera(QColor bgColour, QColor gradientColour); + std::shared_ptr mResourceSystem; Lighting* mLighting; - + + osg::ref_ptr mGradientCamera; osg::Vec4f mDefaultAmbient; bool mHasDefaultAmbient; bool mIsExterior;