第37.1节 框选-绘制框选框

news/2024/11/9 5:03:26/

目录

  • 首先祝大家国庆快乐
  • 本节内容
    • 实现要点
      • 以下为全部代码

首先祝大家国庆快乐

本节内容

本节开始介绍鼠标选择的操作。正常情况下我们都会在场景中使用鼠标框选一些物体。本节我们绘制了框选框,程序启动后,按住键盘上的左CTRL键,然后鼠标在场景中拖动,会出来一个白色的框,符合框选的习惯。如下图所示:
在这里插入图片描述
本节代码在如下网盘中,根据章节编号有对应附件,请使用浏览器打开,平时遇到问题或加群也可以加我微信:13324598743:
【击此打开网盘资源链接】

实现要点

要点只有两个,其它均为正常的绘制和逻辑处理:

  1. 在点下左CTRL的时候,鼠标拖动时要在框选的状态,此时场景的操作器就不起作用了。不能一边选着,场景随着鼠标的拖动还转着,那就不行。此处只需要在事件中返回true,后面的事件处理器就不再处理该事件了。场景也就不转动了 这是个很隐蔽但是又很重要的知识点。具体实现参见MyEvent中的handle,注释较为详尽。
  2. 在屏幕表面绘制一个白色的框要用到HUD,HUD的初始化需要知道当前场景的窗口是多大,而当前的窗口是在viewer.realize之后才创建的,因此需要在viewer.realize之后获取viewport参数之后,再创建HUD中的相机,设置setProjectionMatrix。

以下为全部代码

#include <osgViewer/Viewer>
#include <osgDB/ReadFile>
#include <osg/Camera>
#include <osgGA/GUIEventHandler>//结点的掩码,显示与隐藏
#define NODE_SHOW ~0x0
#define NODE_HIDE 0x0//选择框做为一个全局变量,使用起来方便
osg::Geometry* g_geomSelectBox = new osg::Geometry;//
osg::Camera* createHUD(osg::Viewport* vp)
{osg::Camera* camera = new osg::Camera;//设置投影矩阵为正交投影camera->setProjectionMatrix(osg::Matrix::ortho2D(0, vp->width(), 0, vp->height()));//设置其观察矩阵为单位矩阵,且不改变,该相机永远显示,也不用参与拣选camera->setReferenceFrame(osg::Transform::ABSOLUTE_RF);camera->setViewMatrix(osg::Matrix::identity());//只清空深度缓存,使得其显示内容可以以主相机为背景camera->setClearMask(GL_DEPTH_BUFFER_BIT);//最后渲染,因为需要以主相机显示的内容为背景camera->setRenderOrder(osg::Camera::POST_RENDER);//不需要响应事件camera->setAllowEventFocus(false);//绘制选择框osg::Geode* gnode = new osg::Geode;camera->addChild(gnode);gnode->addDrawable(g_geomSelectBox);//设置透明osg::StateSet* ss = gnode->getOrCreateStateSet();ss->setMode(GL_BLEND, osg::StateAttribute::ON|osg::StateAttribute::OVERRIDE);ss->setRenderingHint(osg::StateSet::TRANSPARENT_BIN);ss->setMode(GL_LIGHTING, osg::StateAttribute::OFF | osg::StateAttribute::OVERRIDE);//设置顶点osg::Vec3Array* vertices = new osg::Vec3Array;float depth = - 0.1;vertices->push_back(osg::Vec3(0, 0, depth));vertices->push_back(osg::Vec3(100, 0, depth));vertices->push_back(osg::Vec3(100, 100, depth));vertices->push_back(osg::Vec3(0, 100, depth));g_geomSelectBox->setVertexArray(vertices);//设置颜色osg::Vec4Array* color = new osg::Vec4Array;color->push_back(osg::Vec4(0.8, 0.8, 0.8, 0.2));g_geomSelectBox->setColorArray(color, osg::Array::BIND_OVERALL);//绘制盒子g_geomSelectBox->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));return camera;
}class MyEvent : public osgGA::GUIEventHandler
{
public:MyEvent() :osgGA::GUIEventHandler(),_xStart(0),_yStart(0){}virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa){//左ctrl按着,又鼠标点击,则进入绘制状态if (ea.getEventType() == ea.PUSH) //{//判断左CTRL键是否按下if (ea.getModKeyMask() == ea.MODKEY_LEFT_CTRL){_xStart = ea.getX();_yStart = ea.getY();//清空之前绘制的结果,这里仅隐藏即可g_geomSelectBox->setNodeMask(NODE_HIDE);//返回真代表后续事件处理器包括操作器不再处理该事件,就实现了拖动时场景不动return true;}}//左ctrl点下时,进入到选择状态,开始绘制选择框,且操作器不再处理鼠标拖动事件if (ea.getEventType() == ea.DRAG) //鼠标拖动,拖动是鼠标按键按下的时候移动鼠标{//判断左CTRL键是否按下if (ea.getModKeyMask() == ea.MODKEY_LEFT_CTRL){//开始绘制,调整顶点参数就可以g_geomSelectBox->setNodeMask(NODE_SHOW);//获取顶点、更新顶点osg::Vec3Array* vertices = (osg::Vec3Array*)g_geomSelectBox->getVertexArray();int xEnd = ea.getX();int yEnd = ea.getY();float depth = -0.1;vertices->at(0).set(_xStart, _yStart, depth);vertices->at(1).set(xEnd, _yStart, depth);vertices->at(2).set(xEnd, yEnd, depth);vertices->at(3).set(_xStart, yEnd, depth);//重绘g_geomSelectBox->dirtyDisplayList();//返回真代表后续事件处理器包括操作器不再处理该事件,就实现了拖动时场景不动return true;}}return false;}int _xStart, _yStart;
};int main()
{osgViewer::Viewer viewer;osg::Group* root = new osg::Group;root->addChild(osgDB::readNodeFile("cow.osg"));viewer.setSceneData(root);viewer.realize();//realize之后,上下文已经被初始化,可以获得视口大小//在此处获得视口大小是为了创建HUD时使其视口大小与创建的一致osg::Viewport* vp = viewer.getCamera()->getViewport();root->addChild(createHUD(vp));viewer.addEventHandler(new MyEvent);return viewer.run();
}

http://www.ppmy.cn/news/544414.html

相关文章

python PyQt5如何绘制矩形框?(画框/绘框)

参考代码&#xff1a; from PyQt5.QtWidgets import QWidget, QApplication, QLabel from PyQt5.QtCore import QRect, Qt from PyQt5.QtGui import QImage, QPixmap, QPainter, QPen, QGuiApplication import cv2 import sys class MyLabel(QLabel):x0 0y0 0x1 0y1 0flag…

使用opencv画框

在平常使用图像处理中的时候&#xff0c;例如检测追踪的时候&#xff0c;我们经常需要用到画图函数&#xff0c;例如手动标定一个目标&#xff0c;调用鼠标时间&#xff0c;然后进行追踪&#xff0c;或者检测完一个目标&#xff0c;画上矩形或者其他形状&#xff0c;然后进行追…

一系列点画框(不规则框)

做个记录&#xff1a;先求点的凸包&#xff0c;再画 void draw_hull() {int w 600;int h 500;cv::Mat polyImg cv::Mat::zeros(w,h,CV_8UC3);std::vector<Point> planevKeys {{159 , 64}, {136 , 74 }, {178 , 34 }, {132 , 89 },{124 , 112}, {178 , 50 },{101 , …

尝试修改LabelImg,将以对顶角画框改成以对角线相交点向四周画框

文章目录 缩小代码位置范围对缩小的范围查找代码shape.py 2020040320200409修改了以下handleDrawing()里的代码&#xff0c;现在能够把框画成这样子了&#xff0c;但是初始点和实时绘制还不知道怎么处理后开在这加上这句之后就能将结果准确绘制了&#xff0c;但是实时显示还是没…

[HNOI2014]画框

画框 题解 多简单的一道题呀&#xff01; 看到这道题&#xff0c;我们应该很容易想到要把 ∑ A i , p i \sum A_{i,p_{i}} ∑Ai,pi​​与 ∑ B i , p i \sum B_{i,p_{i}} ∑Bi,pi​​转化一下。毕竟直接处理这两个的积应该是十分麻烦的。 看到积我们想起了什么呢&#xff1f…

opengl 在显示的图像视频上画框

在前面的博客中opengl 显示BMP图像&#xff0c;总结了如何使用opengl显示BMP图像&#xff0c;如何显示BMP图像序列。 在做Object detection的一些工作中&#xff0c;经常会将检测到object用一个框标记出来&#xff0c;这次探索一下如何实现这个功能。 这要使用Opengl的blend功…

OpenCV画框函数rectangle的使用

OPenCV版本&#xff1a;4.4 IDE&#xff1a;VS2019 功能描述 绘制一个简单的、粗的或填充边界的矩形。 函数cv:&#xff1a;rectangle绘制一个矩形轮廓或一个填充矩形&#xff0c;其两个相对的角是pt1和pt2。 函数原型1 void cv::rectangle ( InputOutputArray img, Point …

JS 画框操作

Js中&#xff0c;我们有时候需要对图片进行操作&#xff0c;包括画框&#xff0c;其实对于UI前端来说挺简单的&#xff0c;没有网上说的那样复杂&#xff0c;这里说明一下 <div style"width:80%;height:300px;position:relative"><img src"img/10.jpg&…