void CornerPinOverlayInteract::drawOverlay(TimeValue time, const RenderScale & /*renderScale*/, ViewIdx /*view*/) { // do not show interact if knob is secret or not enabled // see https://github.com/MrKepzie/Natron/issues/932 KnobDoublePtr from1Knob = _imp->from[0].lock(); if ( !from1Knob || !from1Knob->shouldDrawOverlayInteract() ) { return; } OfxRGBColourD color; if ( !getOverlayColor(color.r, color.g, color.b) ) { color.r = color.g = color.b = 0.8; } RenderScale pscale; getPixelScale(pscale.x, pscale.y); OfxPointD to[4]; OfxPointD from[4]; bool enable[4]; bool useFrom; if (_imp->dragging == -1) { for (int i = 0; i < 4; ++i) { _imp->getFrom(time, i, &from[i].x, &from[i].y); _imp->getTo(time, i, &to[i].x, &to[i].y); enable[i] = _imp->getEnabled(time, i); } useFrom = _imp->getUseFromPoints(time); } else { for (int i = 0; i < 4; ++i) { to[i] = _imp->toDrag[i]; from[i] = _imp->fromDrag[i]; enable[i] = _imp->enableDrag[i]; } useFrom = _imp->useFromDrag; } if (!useFrom && !_imp->areToPointsAnimated()) { return; } OfxPointD p[4]; OfxPointD q[4]; int enableBegin = 4; int enableEnd = 0; for (int i = 0; i < 4; ++i) { if (enable[i]) { if (useFrom) { p[i] = from[i]; q[i] = to[i]; } else { q[i] = from[i]; p[i] = to[i]; } if (i < enableBegin) { enableBegin = i; } if (i + 1 > enableEnd) { enableEnd = i + 1; } } } double w, h; getViewportSize(w, h); GLdouble projection[16]; GL_GPU::GetDoublev( GL_PROJECTION_MATRIX, projection); OfxPointD shadow; // how much to translate GL_PROJECTION to get exactly one pixel on screen shadow.x = 2. / (projection[0] * w); shadow.y = 2. / (projection[5] * h); //glPushAttrib(GL_ALL_ATTRIB_BITS); // caller is responsible for protecting attribs //glDisable(GL_LINE_STIPPLE); GL_GPU::Enable(GL_LINE_SMOOTH); //glEnable(GL_POINT_SMOOTH); GL_GPU::Enable(GL_BLEND); GL_GPU::Hint(GL_LINE_SMOOTH_HINT, GL_DONT_CARE); GL_GPU::LineWidth(1.5f); GL_GPU::BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); GL_GPU::PointSize( CornerPinOverlayInteractPrivate::pointSize() ); // Draw everything twice // l = 0: shadow // l = 1: drawing for (int l = 0; l < 2; ++l) { // shadow (uses GL_PROJECTION) GL_GPU::MatrixMode(GL_PROJECTION); int direction = (l == 0) ? 1 : -1; // translate (1,-1) pixels GL_GPU::Translated(direction * shadow.x, -direction * shadow.y, 0); GL_GPU::MatrixMode(GL_MODELVIEW); // Modelview should be used on Nuke GL_GPU::Color3f( (float)(color.r / 2) * l, (float)(color.g / 2) * l, (float)(color.b / 2) * l ); GL_GPU::Begin(GL_LINES); for (int i = enableBegin; i < enableEnd; ++i) { if (enable[i]) { GL_GPU::Vertex2d(p[i].x, p[i].y); GL_GPU::Vertex2d(q[i].x, q[i].y); } } GL_GPU::End(); GL_GPU::Color3f( (float)color.r * l, (float)color.g * l, (float)color.b * l ); GL_GPU::Begin(GL_LINE_LOOP); for (int i = enableBegin; i < enableEnd; ++i) { if (enable[i]) { GL_GPU::Vertex2d(p[i].x, p[i].y); } } GL_GPU::End(); GL_GPU::Begin(GL_POINTS); for (int i = enableBegin; i < enableEnd; ++i) { if (enable[i]) { if ( (_imp->hovering == i) || (_imp->dragging == i) ) { GL_GPU::Color3f(0.f * l, 1.f * l, 0.f * l); } else { GL_GPU::Color3f( (float)color.r * l, (float)color.g * l, (float)color.b * l ); } GL_GPU::Vertex2d(p[i].x, p[i].y); } } GL_GPU::End(); for (int i = enableBegin; i < enableEnd; ++i) { if (enable[i]) { std::string text = useFrom ? _imp->from[i].lock()->getName().c_str() : _imp->to[i].lock()->getName().c_str() ; getLastCallingViewport()->renderText(p[i].x, p[i].y, text, color.r * l , color.g * l, color.b * l, 1); } } } //glPopAttrib(); } // drawOverlay
void PointOverlayInteract::drawOverlay(TimeValue time, const RenderScale & /*renderScale*/, ViewIdx /*view*/) { KnobDoublePtr knob = _imp->param.lock(); // do not show interact if knob is secret or not enabled // see https://github.com/MrKepzie/Natron/issues/932 if ( !knob || !knob->shouldDrawOverlayInteract()) { return; } ColorRgba<double> color; if ( !getOverlayColor(color.r, color.g, color.b) ) { color.r = color.g = color.b = 0.8; } RenderScale pscale; getPixelScale(pscale.x, pscale.y); float pR = 1.f; float pG = 1.f; float pB = 1.f; switch (_imp->state) { case ePositionInteractStateInactive: pR = (float)color.r; pG = (float)color.g; pB = (float)color.b; break; case ePositionInteractStatePoised: pR = 0.f; pG = 1.0f; pB = 0.0f; break; case ePositionInteractStatePicked: pR = 0.f; pG = 1.0f; pB = 0.0f; break; } QPointF pos; if (_imp->state == ePositionInteractStatePicked) { pos = _imp->lastPenPos; } else { double p[2]; for (int i = 0; i < 2; ++i) { p[i] = knob->getValueAtTime(time, DimIdx(i)); if (knob->getValueIsNormalized(DimIdx(i)) != eValueIsNormalizedNone) { p[i] = knob->denormalize(DimIdx(i), time, p[i]); } } pos.setX(p[0]); pos.setY(p[1]); } //glPushAttrib(GL_ALL_ATTRIB_BITS); // caller is responsible for protecting attribs GL_GPU::PointSize( (GLfloat)_imp->pointSize() ); // Draw everything twice // l = 0: shadow // l = 1: drawing double w, h; getViewportSize(w, h); GLdouble projection[16]; GL_GPU::GetDoublev( GL_PROJECTION_MATRIX, projection); OfxPointD shadow; // how much to translate GL_PROJECTION to get exactly one pixel on screen shadow.x = 2. / (projection[0] * w); shadow.y = 2. / (projection[5] * h); int fmHeight = getLastCallingViewport()->getWidgetFontHeight(); for (int l = 0; l < 2; ++l) { // shadow (uses GL_PROJECTION) GL_GPU::MatrixMode(GL_PROJECTION); int direction = (l == 0) ? 1 : -1; // translate (1,-1) pixels GL_GPU::Translated(direction * shadow.x, -direction * shadow.y, 0); GL_GPU::MatrixMode(GL_MODELVIEW); // Modelview should be used on Nuke GL_GPU::Color3f(pR * l, pG * l, pB * l); GL_GPU::Begin(GL_POINTS); GL_GPU::Vertex2d( pos.x(), pos.y() ); GL_GPU::End(); getLastCallingViewport()->renderText(pos.x(), pos.y() - ( fmHeight + _imp->pointSize() ) * pscale.y, knob->getOriginalName(), pR*l, pG*l, pB*l, 1.); } } // drawOverlay