void RenderableGadget::doRender( const Style *style ) const { if( IECoreGL::Selector::currentSelector() ) { // our scene may contain shaders which don't work with // the selector so we early out for now. we could override // the base state with an appropriate selection shader and // a name component matching the name for the gadget, but // right now we have no need for that. return; } if( m_scene ) { m_scene->render( m_baseState.get() ); } if( m_dragSelecting ) { const ViewportGadget *viewportGadget = ancestor<ViewportGadget>(); ViewportGadget::RasterScope rasterScope( viewportGadget ); Box2f b; b.extendBy( viewportGadget->gadgetToRasterSpace( m_dragStartPosition, this ) ); b.extendBy( viewportGadget->gadgetToRasterSpace( m_lastDragPosition, this ) ); style->renderSelectionBox( b ); } }
void LayersDialog::update(float elapsed_time) { if (layering() == NULL) return; vector< DialogBin > &bins = layering()->bins; float &dialog_tween = layering()->dialog_tween; dialog_tween += elapsed_time; if (dialog_tween > 1.0f) dialog_tween = 1.0f; for (unsigned int b = 0; b < bins.size(); ++b) { Box2f box = bins[b].get_box(dialog_tween); if (box.contains(mouse_pos)) { bins[b].arrows += elapsed_time * 4.0f; if (bins[b].arrows > 1.0f) bins[b].arrows = 1.0f; } else { bins[b].arrows -= elapsed_time * 1.5f; if (bins[b].arrows < 0.0f) bins[b].arrows = 0.0f; } Box2f tex = bins[b].get_tex_box(dialog_tween); if (tex.contains(mouse_pos)) { bins[b].zoom_out += elapsed_time * 3.0f; if (bins[b].zoom_out > 1.0f) bins[b].zoom_out = 1.0f; } else { bins[b].zoom_out -= elapsed_time * 3.0f; if (bins[b].zoom_out < 0.0f) bins[b].zoom_out = 0.0f; } } }
void updateDragRectangle( const GafferUI::DragDropEvent &event, RectangleChangedReason reason ) { const V2f p = eventPosition( event ); Box2f b = m_dragStartRectangle; if( m_xDragEdge == -1 ) { b.min.x = p.x; } else if( m_xDragEdge == 1 ) { b.max.x = p.x; } if( m_yDragEdge == -1 ) { b.min.y = p.y; } else if( m_yDragEdge == 1 ) { b.max.y = p.y; } // fix max < min issues Box2f c; c.extendBy( b.min ); c.extendBy( b.max ); setRectangleInternal( c, reason ); }
void CameraController::setResolution( const Imath::V2i &resolution, ScreenWindowAdjustment adjustment ) { const V2i oldResolution = m_data->resolution->readable(); const Box2f oldScreenWindow = m_data->screenWindow->readable(); m_data->resolution->writable() = resolution; Box2f newScreenWindow; if( adjustment == ScaleScreenWindow ) { const float oldAspect = (float)oldResolution.x/(float)oldResolution.y; const float badAspect = (float)resolution.x/(float)resolution.y; const float yScale = oldAspect / badAspect; newScreenWindow = oldScreenWindow; newScreenWindow.min.y *= yScale; newScreenWindow.max.y *= yScale; } else { const V2f screenWindowCenter = oldScreenWindow.center(); const V2f scale = V2f( resolution ) / V2f( oldResolution ); newScreenWindow.min = (oldScreenWindow.min - screenWindowCenter) * scale; newScreenWindow.max = (oldScreenWindow.max - screenWindowCenter) * scale; } m_data->screenWindow->writable() = newScreenWindow; }
void GraphGadget::updateDragSelection( bool dragEnd ) { Box2f selectionBound; selectionBound.extendBy( m_dragStartPosition ); selectionBound.extendBy( m_lastDragPosition ); for( NodeGadgetMap::const_iterator it = m_nodeGadgets.begin(), eIt = m_nodeGadgets.end(); it != eIt; ++it ) { NodeGadget *nodeGadget = it->second.gadget; const Box3f nodeBound3 = nodeGadget->transformedBound(); const Box2f nodeBound2( V2f( nodeBound3.min.x, nodeBound3.min.y ), V2f( nodeBound3.max.x, nodeBound3.max.y ) ); if( boxContains( selectionBound, nodeBound2 ) ) { nodeGadget->setHighlighted( true ); if( dragEnd ) { m_scriptNode->selection()->add( const_cast<Gaffer::Node *>( it->first ) ); } } else { nodeGadget->setHighlighted( m_scriptNode->selection()->contains( it->first ) ); } } }
ViewportGadget::SelectionScope::SelectionScope( const Imath::V3f &corner0InGadgetSpace, const Imath::V3f &corner1InGadgetSpace, const Gadget *gadget, std::vector<IECoreGL::HitRecord> &selection, IECoreGL::Selector::Mode mode ) : m_selection( selection ) { const ViewportGadget *viewportGadget = gadget->ancestor<ViewportGadget>(); Box2f rasterRegion; rasterRegion.extendBy( viewportGadget->gadgetToRasterSpace( corner0InGadgetSpace, gadget ) ); rasterRegion.extendBy( viewportGadget->gadgetToRasterSpace( corner1InGadgetSpace, gadget ) ); begin( viewportGadget, rasterRegion, gadget->fullTransform(), mode ); }
void CameraController::frame( const Imath::Box3f &box, const Imath::V3f &viewDirection, const Imath::V3f &upVector ) { // make a matrix to centre the camera on the box, with the appropriate view direction M44f cameraMatrix = rotationMatrixWithUpDir( V3f( 0, 0, -1 ), viewDirection, upVector ); M44f translationMatrix; translationMatrix.translate( box.center() ); cameraMatrix *= translationMatrix; // translate the camera back until the box is completely visible M44f inverseCameraMatrix = cameraMatrix.inverse(); Box3f cBox = transform( box, inverseCameraMatrix ); Box2f screenWindow = m_data->screenWindow->readable(); if( m_data->projection->readable()=="perspective" ) { // perspective. leave the field of view and screen window as is and translate // back till the box is wholly visible. this currently assumes the screen window // is centred about the camera axis. float z0 = cBox.size().x / screenWindow.size().x; float z1 = cBox.size().y / screenWindow.size().y; m_data->centreOfInterest = std::max( z0, z1 ) / tan( M_PI * m_data->fov->readable() / 360.0 ) + cBox.max.z + m_data->clippingPlanes->readable()[0]; cameraMatrix.translate( V3f( 0.0f, 0.0f, m_data->centreOfInterest ) ); } else { // orthographic. translate to front of box and set screen window // to frame the box, maintaining the aspect ratio of the screen window. m_data->centreOfInterest = cBox.max.z + m_data->clippingPlanes->readable()[0] + 0.1; // 0.1 is a fudge factor cameraMatrix.translate( V3f( 0.0f, 0.0f, m_data->centreOfInterest ) ); float xScale = cBox.size().x / screenWindow.size().x; float yScale = cBox.size().y / screenWindow.size().y; float scale = std::max( xScale, yScale ); V2f newSize = screenWindow.size() * scale; screenWindow.min.x = cBox.center().x - newSize.x / 2.0f; screenWindow.min.y = cBox.center().y - newSize.y / 2.0f; screenWindow.max.x = cBox.center().x + newSize.x / 2.0f; screenWindow.max.y = cBox.center().y + newSize.y / 2.0f; } m_data->transform->matrix = cameraMatrix; m_data->screenWindow->writable() = screenWindow; }
void CameraController::track( const Imath::V2f &p ) { V2i resolution = m_data->resolution->readable(); Box2f screenWindow = m_data->screenWindow->readable(); V2f d = p - m_data->motionStart; V3f translate( 0.0f ); translate.x = -screenWindow.size().x * d.x/(float)resolution.x; translate.y = screenWindow.size().y * d.y/(float)resolution.y; if( m_data->projection->readable()=="perspective" && m_data->fov ) { translate *= tan( M_PI * m_data->fov->readable() / 360.0f ) * (float)m_data->centreOfInterest; } M44f t = m_data->motionMatrix; t.translate( translate ); m_data->transform->matrix = t; }
void CropWindowTool::preRender() { const Box2f resolutionGate = static_cast<SceneView *>( view() )->resolutionGate(); if( resolutionGate.isEmpty() ) { m_overlay->setVisible( false ); return; } if( !activePlug()->getValue() ) { return; } m_overlay->setVisible( true ); if( !m_overlayDirty ) { return; } Box2f cropWindow( V2f( 0 ), V2f( 1 ) ); findCropWindowPlug(); if( m_cropWindowPlug ) { cropWindow = m_cropWindowPlug->getValue(); } BlockedConnection blockedConnection( m_overlayRectangleChangedConnection ); m_overlay->setRectangle( Box2f( V2f( lerp( resolutionGate.min.x, resolutionGate.max.x, cropWindow.min.x ), lerp( resolutionGate.min.y, resolutionGate.max.y, cropWindow.min.y ) ), V2f( lerp( resolutionGate.min.x, resolutionGate.max.x, cropWindow.max.x ), lerp( resolutionGate.min.y, resolutionGate.max.y, cropWindow.max.y ) ) ) ); m_overlayDirty = false; }
bool LayersDialog::handle_event(SDL_Event const &event, Vector2f local_mouse) { mouse_pos = local_mouse; if (layering() == NULL) return false; if (event.type == SDL_MOUSEBUTTONDOWN) { vector< DialogBin > const &bins = layering()->bins; ListGraph &stacking = layering()->stacking; const float dialog_tween = layering()->dialog_tween; const vector< vector< uint32_t > > &layers = layering()->layers; const Vector2ui dialog_point = layering()->dialog_point; const vector< uint32_t > &tags = layering()->tags; const unsigned int width = layering()->width; const unsigned int height = layering()->height; for (unsigned int b = 0; b < bins.size(); ++b) { Box2f box = bins[b].get_box(dialog_tween); if (box.contains(local_mouse)) { if (bins[b].layer >= layers.size()) continue; bool up = local_mouse.y > box.center().y; if (dialog_point.x < width && dialog_point.y < height && tags.size() == width * height) { unsigned int t = tags[dialog_point.y * width + dialog_point.x]; assert(t < stacking.lists.size()); for (unsigned int i = 0; i < stacking.lists[t].size(); ++i) { if (stacking.lists[t][i] == bins[b].layer) { if (up && i + 1 < stacking.lists[t].size()) { stacking.flip_rel(t, bins[b].layer, stacking.lists[t][i+1], true); layering()->update_image(); } if (!up && i - 1 < stacking.lists[t].size()) { stacking.flip_rel(t, bins[b].layer, stacking.lists[t][i-1], false); layering()->update_image(); } break; } } } return true; } } } return false; }
void CameraController::dolly( const Imath::V2f &p ) { V2i resolution = m_data->resolution->readable(); V2f dv = V2f( (p - m_data->motionStart) ) / resolution; float d = dv.x - dv.y; if( m_data->projection->readable()=="perspective" ) { // perspective m_data->centreOfInterest = m_data->motionCentreOfInterest * expf( -1.9f * d ); M44f t = m_data->motionMatrix; t.translate( V3f( 0, 0, m_data->centreOfInterest - m_data->motionCentreOfInterest ) ); m_data->transform->matrix = t; } else { // orthographic Box2f screenWindow = m_data->motionScreenWindow; V2f centreNDC = V2f( m_data->motionStart ) / resolution; V2f centre( lerp( screenWindow.min.x, screenWindow.max.x, centreNDC.x ), lerp( screenWindow.max.y, screenWindow.min.y, centreNDC.y ) ); float newWidth = m_data->motionScreenWindow.size().x * expf( -1.9f * d ); newWidth = std::max( newWidth, 0.01f ); float scale = newWidth / screenWindow.size().x; screenWindow.min = (screenWindow.min - centre) * scale + centre; screenWindow.max = (screenWindow.max - centre) * scale + centre; m_data->screenWindow->writable() = screenWindow; } }
bool GraphGadget::dragEnd( GadgetPtr gadget, const DragDropEvent &event ) { DragMode dragMode = m_dragMode; m_dragMode = None; Pointer::set( 0 ); if( !m_scriptNode ) { return false; } V3f i; if( !event.line.intersect( Plane3f( V3f( 0, 0, 1 ), 0 ), i ) ) { return false; } if( dragMode == Moving ) { if ( m_dragReconnectCandidate ) { if ( m_dragReconnectDstNodule || m_dragReconnectSrcNodule ) { Gaffer::Plug *srcPlug = m_dragReconnectCandidate->srcNodule()->plug(); Gaffer::Plug *dstPlug = m_dragReconnectCandidate->dstNodule()->plug(); Gaffer::UndoContext undoContext( m_scriptNode ); if ( m_dragReconnectDstNodule ) { m_dragReconnectDstNodule->plug()->setInput( srcPlug ); dstPlug->setInput( 0 ); } if ( m_dragReconnectSrcNodule ) { dstPlug->setInput( m_dragReconnectSrcNodule->plug() ); } } } m_dragReconnectCandidate = 0; renderRequestSignal()( this ); } else if( dragMode == Selecting ) { Box2f selectionBound; selectionBound.extendBy( m_dragStartPosition ); selectionBound.extendBy( m_lastDragPosition ); for( ChildContainer::const_iterator it=children().begin(); it!=children().end(); it++ ) { NodeGadgetPtr nodeGadget = runTimeCast<NodeGadget>( *it ); if( nodeGadget ) { Box3f nodeBound3 = nodeGadget->transformedBound(); Box2f nodeBound2( V2f( nodeBound3.min.x, nodeBound3.min.y ), V2f( nodeBound3.max.x, nodeBound3.max.y ) ); if( boxContains( selectionBound, nodeBound2 ) ) { m_scriptNode->selection()->add( nodeGadget->node() ); } } } renderRequestSignal()( this ); } return true; }
void BackdropNodeGadget::doRender( const Style *style ) const { // this is our bound in gadget space Box2f bound = boundPlug()->getValue(); // but because we're going to draw our contents at an arbitrary scale, // we need to compute a modified bound which will be in the right place // following scaling. const Backdrop *backdrop = static_cast<const Backdrop *>( node() ); const float scale = backdrop->scalePlug()->getValue(); bound.min /= scale; bound.max /= scale; glPushMatrix(); glScalef( scale, scale, scale ); const Box3f titleCharacterBound = style->characterBound( Style::HeadingText ); const float titleBaseline = bound.max.y - g_margin - titleCharacterBound.max.y; if( IECoreGL::Selector::currentSelector() ) { // when selecting we render in a simplified form. // we only draw a thin strip around the edge of the backdrop // to allow the edges to be grabbed for dragging, and a strip // at the top to allow the title header to be grabbed for moving // around. leaving the main body of the backdrop as a hole is // necessary to allow the GraphGadget to continue to perform // drag selection on the nodes on top of the backdrop. const float width = hoverWidth() / scale; style->renderSolidRectangle( Box2f( bound.min, V2f( bound.min.x + width, bound.max.y ) ) ); // left style->renderSolidRectangle( Box2f( V2f( bound.max.x - width, bound.min.y ), bound.max ) ); // right style->renderSolidRectangle( Box2f( bound.min, V2f( bound.max.x, bound.min.y + width ) ) ); // bottom style->renderSolidRectangle( Box2f( V2f( bound.min.x, bound.max.y - width ), bound.max ) ); // top style->renderSolidRectangle( Box2f( V2f( bound.min.x, titleBaseline - g_margin ), bound.max ) ); // heading } else { // normal drawing mode style->renderBackdrop( bound, getHighlighted() ? Style::HighlightedState : Style::NormalState ); const std::string title = backdrop->titlePlug()->getValue(); if( title.size() ) { Box3f titleBound = style->textBound( Style::HeadingText, title ); glPushMatrix(); glTranslatef( bound.center().x - titleBound.size().x / 2.0f, titleBaseline, 0.0f ); style->renderText( Style::HeadingText, title ); glPopMatrix(); } if( m_hovered ) { style->renderHorizontalRule( V2f( bound.center().x, titleBaseline - g_margin / 2.0f ), bound.size().x - g_margin * 2.0f, Style::HighlightedState ); } Box2f textBound = bound; textBound.min += V2f( g_margin ); textBound.max = V2f( textBound.max.x - g_margin, titleBaseline - g_margin ); if( textBound.hasVolume() ) { std::string description = backdrop->descriptionPlug()->getValue(); style->renderWrappedText( Style::BodyText, description, textBound ); } } glPopMatrix(); }
void ImageGadget::doRender( const GafferUI::Style *style ) const { if( IECoreGL::Selector::currentSelector() ) { return; } // Compute what we need, and abort rendering if // there are any computation errors. Format format; Box2i dataWindow; try { format = this->format(); dataWindow = this->dataWindow(); updateTiles(); } catch( ... ) { return; } // Early out if the image has no size. const Box2i &displayWindow = format.getDisplayWindow(); if( BufferAlgo::empty( displayWindow ) ) { return; } // Render a black background the size of the image. // We need to account for the pixel aspect ratio here // and in all our drawing. Variables ending in F denote // windows corrected for pixel aspect. const Box2f displayWindowF( V2f( displayWindow.min ) * V2f( format.getPixelAspect(), 1.0f ), V2f( displayWindow.max ) * V2f( format.getPixelAspect(), 1.0f ) ); const Box2f dataWindowF( V2f( dataWindow.min ) * V2f( format.getPixelAspect(), 1.0f ), V2f( dataWindow.max ) * V2f( format.getPixelAspect(), 1.0f ) ); glColor3f( 0.0f, 0.0f, 0.0f ); style->renderSolidRectangle( displayWindowF ); if( !BufferAlgo::empty( dataWindow ) ) { style->renderSolidRectangle( dataWindowF ); } // Draw the image tiles over the top. renderTiles(); // And add overlays for the display and data windows. glColor3f( 0.1f, 0.1f, 0.1f ); style->renderRectangle( displayWindowF ); string formatText = Format::name( format ); const string dimensionsText = lexical_cast<string>( displayWindow.size().x ) + " x " + lexical_cast<string>( displayWindow.size().y ); if( formatText.empty() ) { formatText = dimensionsText; } else { formatText += " ( " + dimensionsText + " )"; } renderText( formatText, V2f( displayWindowF.center().x, displayWindowF.min.y ), V2f( 0.5, 1.5 ), style ); if( displayWindow.min != V2i( 0 ) ) { renderText( lexical_cast<string>( displayWindow.min ), displayWindowF.min, V2f( 1, 1.5 ), style ); renderText( lexical_cast<string>( displayWindow.max ), displayWindowF.max, V2f( 0, -0.5 ), style ); } if( !BufferAlgo::empty( dataWindow ) && dataWindow != displayWindow ) { glColor3f( 0.5f, 0.5f, 0.5f ); style->renderRectangle( dataWindowF ); if( dataWindow.min != displayWindow.min ) { renderText( lexical_cast<string>( dataWindow.min ), dataWindowF.min, V2f( 1, 1.5 ), style ); renderText( lexical_cast<string>( dataWindow.max ), dataWindowF.max, V2f( 0, -0.5 ), style ); } } }
void QtOutline2Rasterizer::rasterize(RasterizedOutline2 &poly, float scale, int rast_i, int rotationNum, int cellSize) { float rotRad = M_PI*2.0f*float(rast_i) / float(rotationNum); //get polygon's BB, rotated according to the input parameter Box2f bb; vector<Point2f> pointvec = poly.getPoints(); for(size_t i=0;i<pointvec.size();++i) { Point2f pp=pointvec[i]; pp.Rotate(rotRad); bb.Add(pp); } ///CREATE ITS GRID. The grid has to be a multiple of CELLSIZE because this grid's cells have size CELLSIZE //we'll make so that sizeX and sizeY are multiples of CELLSIZE: //1) we round it to the next integer //2) add the number which makes it a multiple of CELLSIZE (only if it's not multiple already) int sizeX = (int)ceil(bb.DimX()*scale); int sizeY = (int)ceil(bb.DimY()*scale); if (sizeX % cellSize != 0) sizeX += (cellSize - ((int)ceil(bb.DimX()*scale) % cellSize)); if (sizeY % cellSize != 0) sizeY += (cellSize - ((int)ceil(bb.DimY()*scale) % cellSize)); //security measure: add a dummy column/row thus making the image bigger, and crop it afterwards //(if it hasn't been filled with anything) //this is due to the fact that if we have a rectangle which has bb 39.xxx wide, then it won't fit in a 40px wide QImage!! The right side will go outside of the image!! :/ sizeX+=cellSize; sizeY+=cellSize; QImage img(sizeX,sizeY,QImage::Format_RGB32); QColor backgroundColor(Qt::transparent); img.fill(backgroundColor); ///SETUP OF DRAWING PROCEDURE QPainter painter; painter.begin(&img); QBrush br; br.setStyle(Qt::SolidPattern); QPen qp; qp.setWidthF(0); qp.setColor(Qt::yellow); painter.setBrush(br); painter.setPen(qp); painter.resetTransform(); painter.translate(QPointF(-(bb.min.X()*scale) , -(bb.min.Y()*scale) )); painter.rotate(math::ToDeg(rotRad)); painter.scale(scale,scale); //create the polygon to print it QVector<QPointF> points; vector<Point2f> newpoints = poly.getPoints(); for (size_t i = 0; i < newpoints.size(); i++) { points.push_back(QPointF(newpoints[i].X(), newpoints[i].Y())); } painter.drawPolygon(QPolygonF(points)); //CROPPING: it is enough to check for the (end - cellSize - 1)th row/col of pixels, if they're all black we can eliminate the last 8columns/rows of pixels bool cropX = true; bool cropY = true; for (int j=0; j<img.height(); j++) { const uchar* line = img.scanLine(j); if (j == img.height() - (cellSize - 1) - 1 ) { for (int x=0; x<img.width(); x++) { if (((QRgb*)line)[x] != backgroundColor.rgb()) { cropY = false; break; } } } else { if (((QRgb*)line)[img.width() - (cellSize - 1) - 1] != backgroundColor.rgb()) { cropX = false; break; } } if (!cropY) break; } if (cropX || cropY) { painter.end(); img = img.copy(0, 0, img.width() - cellSize * cropX, img.height() - cellSize * cropY); painter.begin(&img); painter.setBrush(br); painter.setPen(qp); } //draw the poly for the second time, this time it is centered to the image img.fill(backgroundColor); painter.resetTransform(); painter.translate(QPointF(-(bb.min.X()*scale) + (img.width() - ceil(bb.DimX()*scale))/2.0, -(bb.min.Y()*scale) + (img.height() - ceil(bb.DimY()*scale))/2.0)); painter.rotate(math::ToDeg(rotRad)); painter.scale(scale,scale); //create the polygon to print it QVector<QPointF> points2; vector<Point2f> newpoints2 = poly.getPoints(); for (size_t i = 0; i < newpoints2.size(); i++) { points2.push_back(QPointF(newpoints2[i].X(), newpoints2[i].Y())); } painter.drawPolygon(QPolygonF(points2)); //create the first grid, which will then be rotated 3 times. //we will reuse this grid to create the rasterizations corresponding to this one rotated by 90/180/270° vector<vector<int> > tetrisGrid; QRgb yellow = QColor(Qt::yellow).rgb(); int gridWidth = img.width() / cellSize; int gridHeight = img.height() / cellSize; int x = 0; tetrisGrid.resize(gridHeight); for (int k = 0; k < gridHeight; k++) { tetrisGrid[k].resize(gridWidth, 0); } for (int y = 0; y < img.height(); y++) { int gridY = y / cellSize; const uchar* line = img.scanLine(y); x = 0; int gridX = 0; while(x < img.width()) { gridX = x/cellSize; if (tetrisGrid[gridY][gridX] == 1) { x+= cellSize - (x % cellSize); //align with the next x continue; } if (((QRgb*)line)[x] == yellow) tetrisGrid[gridY][gridX] = 1; ++x; } } //create the 4 rasterizations (one every 90°) using the discrete representation grid we've just created int rotationOffset = rotationNum/4; for (int j = 0; j < 4; j++) { if (j != 0) { tetrisGrid = rotateGridCWise(tetrisGrid); } //add the grid to the poly's vector of grids poly.getGrids(rast_i + rotationOffset*j) = tetrisGrid; //initializes bottom/left/deltaX/deltaY vectors of the poly, for the current rasterization poly.initFromGrid(rast_i + rotationOffset*j); } painter.end(); }
void GraphGadget::doRender( const Style *style ) const { glDisable( GL_DEPTH_TEST ); // render backdrops before anything else /// \todo Perhaps we need a more general layering system as part /// of the Gadget system, to allow Gadgets to choose their own layering, /// and perhaps to also allow one gadget to draw into multiple layers. for( ChildContainer::const_iterator it=children().begin(); it!=children().end(); it++ ) { if( (*it)->isInstanceOf( (IECore::TypeId)BackdropNodeGadgetTypeId ) ) { static_cast<const Gadget *>( it->get() )->render( style ); } } // then render connections so they go underneath the nodes for( ChildContainer::const_iterator it=children().begin(); it!=children().end(); it++ ) { ConnectionGadget *c = IECore::runTimeCast<ConnectionGadget>( it->get() ); if ( c && c != m_dragReconnectCandidate ) { c->render( style ); } } // render the new drag connections if they exist if ( m_dragReconnectCandidate ) { if ( m_dragReconnectDstNodule ) { const Nodule *srcNodule = m_dragReconnectCandidate->srcNodule(); const NodeGadget *srcNodeGadget = nodeGadget( srcNodule->plug()->node() ); const Imath::V3f srcP = srcNodule->fullTransform( this ).translation(); const Imath::V3f dstP = m_dragReconnectDstNodule->fullTransform( this ).translation(); const Imath::V3f dstTangent = nodeGadget( m_dragReconnectDstNodule->plug()->node() )->noduleTangent( m_dragReconnectDstNodule ); /// \todo: can there be a highlighted/dashed state? style->renderConnection( srcP, srcNodeGadget->noduleTangent( srcNodule ), dstP, dstTangent, Style::HighlightedState ); } if ( m_dragReconnectSrcNodule ) { const Nodule *dstNodule = m_dragReconnectCandidate->dstNodule(); const NodeGadget *dstNodeGadget = nodeGadget( dstNodule->plug()->node() ); const Imath::V3f srcP = m_dragReconnectSrcNodule->fullTransform( this ).translation(); const Imath::V3f dstP = dstNodule->fullTransform( this ).translation(); const Imath::V3f srcTangent = nodeGadget( m_dragReconnectSrcNodule->plug()->node() )->noduleTangent( m_dragReconnectSrcNodule ); /// \todo: can there be a highlighted/dashed state? style->renderConnection( srcP, srcTangent, dstP, dstNodeGadget->noduleTangent( dstNodule ), Style::HighlightedState ); } } // then render the rest on top for( ChildContainer::const_iterator it=children().begin(); it!=children().end(); it++ ) { if( !((*it)->isInstanceOf( ConnectionGadget::staticTypeId() )) && !((*it)->isInstanceOf( (IECore::TypeId)BackdropNodeGadgetTypeId )) ) { static_cast<const Gadget *>( it->get() )->render( style ); } } // render drag select thing if needed if( m_dragMode == Selecting ) { const ViewportGadget *viewportGadget = ancestor<ViewportGadget>(); ViewportGadget::RasterScope rasterScope( viewportGadget ); Box2f b; b.extendBy( viewportGadget->gadgetToRasterSpace( V3f( m_dragStartPosition.x, m_dragStartPosition.y, 0 ), this ) ); b.extendBy( viewportGadget->gadgetToRasterSpace( V3f( m_lastDragPosition.x, m_lastDragPosition.y, 0 ), this ) ); style->renderSelectionBox( b ); } }
MeshPrimitivePtr MeshPrimitive::createPlane( const Box2f &b, const Imath::V2i &divisions ) { V3fVectorDataPtr pData = new V3fVectorData; std::vector<V3f> &p = pData->writable(); // add vertices float xStep = b.size().x / (float)divisions.x; float yStep = b.size().y / (float)divisions.y; for ( int i = 0; i <= divisions.y; ++i ) { for ( int j = 0; j <= divisions.x; ++j ) { p.push_back( V3f( b.min.x + j * xStep, b.min.y + i * yStep, 0 ) ); } } IntVectorDataPtr vertexIds = new IntVectorData; IntVectorDataPtr verticesPerFace = new IntVectorData; std::vector<int> &vpf = verticesPerFace->writable(); std::vector<int> &vIds = vertexIds->writable(); FloatVectorDataPtr sData = new FloatVectorData; FloatVectorDataPtr tData = new FloatVectorData; std::vector<float> &s = sData->writable(); std::vector<float> &t = tData->writable(); float sStep = 1.0f / (float)divisions.x; float tStep = 1.0f / (float)divisions.y; // add faces int v0, v1, v2, v3; for ( int i = 0; i < divisions.y; ++i ) { for ( int j = 0; j < divisions.x; ++j ) { v0 = j + (divisions.x+1) * i; v1 = j + 1 + (divisions.x+1) * i;; v2 = j + 1 + (divisions.x+1) * (i+1); v3 = j + (divisions.x+1) * (i+1); vpf.push_back( 4 ); vIds.push_back( v0 ); vIds.push_back( v1 ); vIds.push_back( v2 ); vIds.push_back( v3 ); s.push_back( j * sStep ); s.push_back( (j+1) * sStep ); s.push_back( (j+1) * sStep ); s.push_back( j * sStep ); t.push_back( 1 - i * tStep ); t.push_back( 1 - i * tStep ); t.push_back( 1 - (i+1) * tStep ); t.push_back( 1 - (i+1) * tStep ); } } MeshPrimitivePtr result = new MeshPrimitive( verticesPerFace, vertexIds, "linear", pData ); result->variables["s"] = PrimitiveVariable( PrimitiveVariable::FaceVarying, sData ); result->variables["t"] = PrimitiveVariable( PrimitiveVariable::FaceVarying, tData ); return result; }
void TexViewerModule::draw(Box2f viewport, Box2f screen_viewport, float scale, unsigned int recurse) { glMatrixMode(GL_PROJECTION); glPushMatrix(); glBoxToBox(viewport, screen_viewport); Vector2f s = size(); glBegin(GL_QUADS); glColor3f(0.0f, 0.0f, 0.0f); glVertex2f(-0.5f*s.x, -0.5f*s.y); glVertex2f( 0.5f*s.x, -0.5f*s.y); glVertex2f( 0.5f*s.x, 0.5f*s.y); glVertex2f(-0.5f*s.x, 0.5f*s.y); glEnd(); if (tex_out().tex != 0) { glDisable(GL_BLEND); glUseProgramObjectARB(scale_bias_shader->handle); glUniform1fARB(glGetUniformLocationARB(scale_bias_shader->handle, "scale"), 1.0f); glUniform1fARB(glGetUniformLocationARB(scale_bias_shader->handle, "bias"), 0.5f); glColor3f(1.0f, 1.0f, 1.0f); glEnable(GL_TEXTURE_RECTANGLE_ARB); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, tex_out().tex); #ifdef ATI_HACK set_nearest(); #else set_linear(); //no ATI_HACK #endif float px_size = 2.0f / Graphics::screen_y * viewport.size().x / screen_viewport.size().x * tex_out().height / size().y; glBegin(GL_QUADS); glColor3f(0.0f, 0.0f, 0.0f); glTexCoord2f(0-0.5f * px_size, 0-0.5f * px_size); glMultiTexCoord2f(GL_TEXTURE1_ARB, 0+0.5f * px_size, 0+0.5f * px_size); if (rotate) { glVertex2f(-0.5f*s.x, -0.5f*s.y); } else { glVertex2f(-0.5f*s.x, 0.5f*s.y); } glTexCoord2f(tex_out().width-0.5f * px_size, 0-0.5f * px_size); glMultiTexCoord2f(GL_TEXTURE1_ARB, tex_out().width+0.5f * px_size, 0+0.5f * px_size); if (rotate) { glVertex2f(-0.5f*s.x, 0.5f*s.y); } else { glVertex2f( 0.5f*s.x, 0.5f*s.y); } glTexCoord2f(tex_out().width-0.5f * px_size, tex_out().height-0.5f * px_size); glMultiTexCoord2f(GL_TEXTURE1_ARB, tex_out().width+0.5f * px_size, tex_out().height+0.5f * px_size); if (rotate) { glVertex2f( 0.5f*s.x, 0.5f*s.y); } else { glVertex2f( 0.5f*s.x, -0.5f*s.y); } glTexCoord2f(0-0.5f * px_size, tex_out().height-0.5f * px_size); glMultiTexCoord2f(GL_TEXTURE1_ARB, 0+0.5f * px_size, tex_out().height+0.5f * px_size); if (rotate) { glVertex2f( 0.5f*s.x, -0.5f*s.y); } else { glVertex2f(-0.5f*s.x, -0.5f*s.y); } glEnd(); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glDisable(GL_TEXTURE_RECTANGLE_ARB); glUseProgramObjectARB(0); glEnable(GL_BLEND); } else { glBegin(GL_LINES); glColor3f(1.0f, 0.0f, 0.0f); glVertex2f(-0.4f*s.x, -0.4f*s.y); glVertex2f( 0.4f*s.x, 0.4f*s.y); glVertex2f( 0.4f*s.x, -0.4f*s.y); glVertex2f(-0.4f*s.x, 0.4f*s.y); glEnd(); } glBegin(GL_LINE_LOOP); glColor3f(1.0f, 1.0f, 1.0f); glVertex2f(-0.5f*s.x, -0.5f*s.y); glVertex2f( 0.5f*s.x, -0.5f*s.y); glVertex2f( 0.5f*s.x, 0.5f*s.y); glVertex2f(-0.5f*s.x, 0.5f*s.y); glEnd(); glPopMatrix(); glMatrixMode(GL_MODELVIEW); Graphics::gl_errors("TexViewer::draw"); }
void LayersDialog::draw(Box2f viewport, Box2f screen_viewport, float scale, unsigned int recurse) { if (!subpixel_shader.ref) { Graphics::ShaderObjectRef frag = Graphics::get_shader_object("ll_shaders/ll_subpixel.glsl", GL_FRAGMENT_SHADER_ARB); assert(frag.ref); subpixel_shader = Graphics::get_program_object(frag); assert(subpixel_shader.ref); glUseProgramObjectARB(subpixel_shader->handle); glUniform1iARB(glGetUniformLocationARB(subpixel_shader->handle, "image"), 0); glUseProgramObjectARB(0); } glMatrixMode(GL_PROJECTION); glPushMatrix(); glBoxToBox(viewport, screen_viewport); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glBegin(GL_QUADS); glColor3f(0.4f, 0.2f, 0.2f); glVertex2f(-size().x*0.5f, -size().y*0.5f); glVertex2f( size().x*0.5f, -size().y*0.5f); glVertex2f( size().x*0.5f, size().y*0.5f); glVertex2f(-size().x*0.5f, size().y*0.5f); glEnd(); if (!layering()) { glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); return; } vector< DialogBin > const &bins = layering()->bins; const float dialog_tween = layering()->dialog_tween; const unsigned int width = layering()->width; const unsigned int height = layering()->height; vector< GLuint > const &textures = layering()->textures; for (unsigned int b = 0; b < bins.size(); ++b) { float alpha = bins[b].active?1.0f:0.3f; Box2f box = bins[b].get_box(dialog_tween); glBegin(GL_QUADS); glColor4f(0.5f, 0.5f, 0.6f, alpha * 0.8f); glVertex2f(box.min.x, box.min.y); glVertex2f(box.max.x, box.min.y); glColor4f(0.9f, 0.85f, 0.83f, alpha * 0.8f); glVertex2f(box.max.x, box.max.y); glVertex2f(box.min.x, box.max.y); glEnd(); Box2f tex = bins[b].get_tex_box(dialog_tween); Vector3f show = bins[b].get_show(dialog_tween, make_vector(width * 0.5f, height * 0.5f, width * 0.5f)); show += bins[b].zoom_out * (make_vector(0.5f * width, 0.5f * height, 0.5f * width) - show); if (bins[b].layer < textures.size()) { float px_size = 2.0f / Graphics::screen_y * viewport.size().x / screen_viewport.size().x * show.z / (tex.max.y - tex.min.y); glUseProgramObjectARB(subpixel_shader->handle); glUniform1fARB(glGetUniformLocationARB(subpixel_shader->handle, "px_size"), px_size); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, textures[bins[b].layer]); } glColor4f(1.0f, 1.0f, 1.0f, alpha); glBegin(GL_QUADS); glTexCoord2f(show.x-show.z,show.y-show.z); glVertex2f(tex.min.x, tex.min.y); glTexCoord2f(show.x+show.z,show.y-show.z); glVertex2f(tex.max.x, tex.min.y); glTexCoord2f(show.x+show.z,show.y+show.z); glVertex2f(tex.max.x, tex.max.y); glTexCoord2f(show.x-show.z,show.y+show.z); glVertex2f(tex.min.x, tex.max.y); glEnd(); glBindTexture(GL_TEXTURE_RECTANGLE_ARB, 0); glUseProgramObjectARB(0); //arrows: float s = box.size().y * (1.0f / 3.0f); glEnable(GL_POLYGON_SMOOTH); glBegin(GL_TRIANGLES); glColor4f(1.0f, 1.0f, 1.0f, 0.5f * alpha * bins[b].arrows); glVertex2f(box.max.x - s * 1.5f, box.max.y - 0.25 * s); glVertex2f(box.max.x - s * 0.75f, box.max.y - 1.25 * s); glVertex2f(box.max.x - s * 2.25f, box.max.y - 1.25 * s); glVertex2f(box.max.x - s * 1.5f, box.min.y + 0.25 * s); glVertex2f(box.max.x - s * 0.75f, box.min.y + 1.25 * s); glVertex2f(box.max.x - s * 2.25f, box.min.y + 1.25 * s); glEnd(); glDisable(GL_POLYGON_SMOOTH); glBegin(GL_LINES); glColor4f(1.0f, 1.0f, 1.0f, 0.5f * alpha * bins[b].arrows); glVertex2f(tex.max.x + box.size().x * 0.05f, box.center().y); glVertex2f(box.max.x - box.size().x * 0.05f, box.center().y); glEnd(); } glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); glPopMatrix(); }