当前位置: 首页 > news >正文

怎么做网页自我介绍广州seo教程

怎么做网页自我介绍,广州seo教程,一起做业网站登录,公司网站设计费计入什么科目目录 1. 需求的提出 2. 具体实现 2.1. 禁止场景跟随鼠标转动 2.2. 矩形框前置绘制 3. 附加说明 3.1. 颜色设置说明 3.2.矩形框显示和隐藏的另一种实现 1. 需求的提出 有时需要在屏幕通过按住键盘上的某个键如Ctrl键且按住鼠标左键,拖出一个矩形,实现框…

目录

1. 需求的提出

2. 具体实现

     2.1. 禁止场景跟随鼠标转动

     2.2. 矩形框前置绘制

3. 附加说明

        3.1. 颜色设置说明

        3.2.矩形框显示和隐藏的另一种实现


1. 需求的提出

       有时需要在屏幕通过按住键盘上的某个键如Ctrl键且按住鼠标左键,拖出一个矩形,实现框选三维物体,如下效果:

现在的问题是:

  1. 在osg中,拖动鼠标时,物体会随鼠标一起转动,这样框选是不行的,至少是不友好的,我们需要的是,按住鼠标框选时,物体不能随鼠标一起转动。
  2. 如何根据鼠标拖动的起始点和终止点,绘制出这个矩形框?矩形框要在所有三维物体的前面而不能被三维物体遮挡且要是透明的,能透过它看到背后的三维物体,否则框选就失去了意义。
  3. 按住鼠标右键,矩形框消失。

2. 具体实现

     2.1. 禁止场景跟随鼠标转动

        对第1节中提到的第1个问题,默认情况下osgViewer::Viewer事件处理器在鼠标左键按下并拖动时,整个场景会随鼠标一起转动。为了不让转动,可以通过改写osgViewer::Viewer osgGA::GUIEventHandler事件处理器,重载如下方法:

 virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, osg::Object* obj, osg::NodeVisitor*nv)

当按住键盘上的某个键如Ctrl键且按住鼠标左键,让该函数返回true,这样后续的流程就不会处理鼠标拖动事件,三维物体也就不会跟随鼠标旋转了。

     2.2. 矩形框前置绘制

         矩形框要绘制在所有三维物体的前面而不能被三维物体遮挡,这就要用到三维中的HUD技术(Head Up Display)。所谓HUD节点,说白了就是无论三维场景中的内容怎么改变,它都能在屏幕上固定位置显示的节点。实现要点:

  • 关闭光照,不受场景光照影响,所有内容以同一亮度显示。
  • 关闭深度测试。
  • 调整渲染顺序,使它的内容最后绘制。
  • 设定参考贴为绝对型:setReferenceFrame(osg::Transform:ABSOLUTE_RF)。
  • 使其不受父节点变换的影响:setMatrix(osg::Matrix::identity())。
  • 使用平行投影,设定虚拟投影窗口的大小,这个窗口的大小决定了后面绘制的图形和文字的尺度比例。

  实现代码如下:

#include<osgViewer/Viewer>
#include<osg/ShapeDrawable>
#include<osgDB/readFile>
#include<osg/BlendFunc>
class selectBoxEventHandler: public osgGA::GUIEventHandler
{
public:selectBoxEventHandler(osg::ref_ptr<osg::Camera> spHudCamera){m_spHudCamera = spHudCamera;}
private:virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, osg::Object* obj, osg::NodeVisitor*nv){m_pViewer = (osgViewer::Viewer*)(&aa);if (m_pViewer == nullptr){return false;}auto width = m_pViewer->getCamera()->getViewport()->width();auto height = m_pViewer->getCamera()->getViewport()->height();/* 设置HUD相机为正投影,这样绘制的矩形框和鼠标拖动的框选框大小就一样了且要设置正投影的区域和视图窗体一样大小,因为鼠标可以在窗体任何位置进行框选*/m_spHudCamera->setProjectionMatrix(osg::Matrix::ortho2D(0, width, 0, height));auto eventType = ea.getEventType();switch (eventType){case osgGA::GUIEventAdapter::KEYDOWN:{if ((osgGA::GUIEventAdapter::KEY_Control_L == ea.getKey()) || (osgGA::GUIEventAdapter::KEY_Control_R == ea.getKey())) // Ctrl键被按下{m_ctrlKeyPressed = true;}}break;case osgGA::GUIEventAdapter::KEYUP:{if ((osgGA::GUIEventAdapter::KEY_Control_L == ea.getKey())|| (osgGA::GUIEventAdapter::KEY_Control_R == ea.getKey())) // Ctrl键被释放{m_ctrlKeyPressed = false;}}break;case osgGA::GUIEventAdapter::PUSH:  // 鼠标左键按下{auto buttonMask = ea.getButtonMask();auto bIsMouseBtn = buttonMask & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON;if (bIsMouseBtn){m_fStartPosX = ea.getX();m_fStartPosY = ea.getY();m_bPush = true;}else if (buttonMask & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) // 鼠标右键按下,则删除选择框{if (m_spOldNode != nullptr){m_spHudCamera->removeChild(m_spOldNode);}}}break;case osgGA::GUIEventAdapter::RELEASE:  // 释放鼠标左键{m_bPush = false;}break;case osgGA::GUIEventAdapter::DRAG:    // 拖动鼠标{auto buttonMask = ea.getButtonMask();auto bIsMouseBtn = buttonMask & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON;if (bIsMouseBtn && m_ctrlKeyPressed && m_bPush){m_fEndPosX = ea.getX();m_fEndPosY = ea.getY();auto pSelectBox = createSelectBox(m_fStartPosX, m_fStartPosY, m_fEndPosX, m_fEndPosY);if (m_spOldNode != nullptr){m_spHudCamera->removeChild(m_spOldNode);}m_spHudCamera->addChild(pSelectBox);m_spOldNode = pSelectBox;return true;}}} // end swithreturn  false;}osg::Geode* createSelectBox(float fStartPosX, float fStartPosY, float fEndPosX, float fEndPosY){osg::Geode* pGeode = new osg::Geode();auto pQuardGeomerty = new osg::Geometry();pGeode->addChild(pQuardGeomerty);osg::Vec3Array* pVertArray = new osg::Vec3Array;pVertArray->push_back(osg::Vec3(fStartPosX, fStartPosY, 0.0));pVertArray->push_back(osg::Vec3(fStartPosX, fEndPosY, 0.0));pVertArray->push_back(osg::Vec3(fEndPosX, fEndPosY, 0.0));pVertArray->push_back(osg::Vec3(fEndPosX, fStartPosY, 0.0));pQuardGeomerty->setVertexArray(pVertArray);osg::Vec4Array* pColorArray = new osg::Vec4Array;pColorArray->push_back(osg::Vec4(1.0, 1.0, 1.0, 0.4));/*  pColorArray->push_back(osg::Vec4(1.0, 1.0, 1.0, 0.40));pColorArray->push_back(osg::Vec4(1.0, 1.0, 1.0, 0.40));pColorArray->push_back(osg::Vec4(1.0, 1.0, 1.0, 0.40));*/pQuardGeomerty->setColorArray(pColorArray);//pQuardGeomerty->setColorBinding(osg::Geometry::AttributeBinding::BIND_PER_VERTEX);pQuardGeomerty->setColorBinding(osg::Geometry::AttributeBinding::BIND_PER_PRIMITIVE_SET);pQuardGeomerty->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));pGeode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); // 关闭光照pGeode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON); // 开启透明,否则就不能透过选择框看到后面的牛pGeode->addDrawable(pQuardGeomerty);return pGeode;}private:/* 鼠标按下的起始坐标点 */float m_fStartPosX{0.0};float m_fStartPosY{ 0.0 };float m_fEndPosX{ 0.0 };float m_fEndPosY{ 0.0 };bool m_ctrlKeyPressed{false};             // Ctrl键被按下bool m_bPush{false};                      // 鼠标左键是否被按下osgViewer::Viewer* m_pViewer{nullptr};osg::ref_ptr<osg::Camera> m_spHudCamera;  // 用于HUD的相机osg::ref_ptr<osg::Node> m_spOldNode;      // 上次鼠标框选绘制出的矩形框};
int main(int argc, char *argv[])
{osgViewer::Viewer viewer;auto cowNode = osgDB::readNodeFile(R"(E:\osg\OpenSceneGraph-Data\cow.osg)");if (nullptr == cowNode){OSG_WARN << "node is null!";return 1;}auto spRoot = new osg::Group();osg::ref_ptr<osg::Camera> spHudCamera = new osg::Camera;spHudCamera->setClearMask(GL_DEPTH_BUFFER_BIT);  // 关闭深度缓冲// 设置渲染顺序为后渲染,即始终在其它绘制物体的上面,防止被其它绘制的物体遮挡spHudCamera->setRenderOrder(osg::Camera::RenderOrder::POST_RENDER); spHudCamera->setAllowEventFocus(false);  // 不接受任何焦点事件,即不响应键盘、鼠标事件spHudCamera->setReferenceFrame(osg::Transform::ReferenceFrame::ABSOLUTE_RF); // 设置参考帧为绝对帧spHudCamera->setViewMatrix(osg::Matrix::identity()); // 设置相机视图矩阵为单位矩阵,这样就矩形框选框就不受相机旋转等变换影响spRoot->addChild(cowNode);spRoot->addChild(spHudCamera);viewer.setSceneData(spRoot);viewer.addEventHandler(new selectBoxEventHandler(spHudCamera));return viewer.run();
}

3. 附加说明

        3.1. 颜色设置说明

              2.2节代码对颜色的设置,也可以按如下代码一样达到同样的效果:

 osg::Vec4Array* pColorArray = new osg::Vec4Array;pColorArray->push_back(osg::Vec4(1.0, 1.0, 1.0, 0.4));pColorArray->push_back(osg::Vec4(1.0, 1.0, 1.0, 0.40));pColorArray->push_back(osg::Vec4(1.0, 1.0, 1.0, 0.40));pColorArray->push_back(osg::Vec4(1.0, 1.0, 1.0, 0.40));pQuardGeomerty->setColorArray(pColorArray);pQuardGeomerty->setColorBinding(osg::Geometry::AttributeBinding::BIND_PER_VERTEX);

也就是说设置一个顶点的颜色且颜色绑定方式为BIND_PER_PRIMITIVE_SET和分别设置4个顶点颜色,颜色绑定方式为BIND_PER_VERTEX效果相同。关于BIND_PER_PRIMITIVE_SET和BIND_PER_VERTEX的具体含义和不同点,请参考:osg图元绑定方式总结博文。

        3.2.矩形框显示和隐藏的另一种实现

       上面矩形框的显示和隐藏是通过removeChild和addChild函数来实现的,即将新的矩形框节点加入到相机作为其子节点之前,删除上次创建的矩形框节点。也可以通过osg::Node的setNodeMask函数来实现,如下为更改后的代码:

#include<osgViewer/Viewer>
#include<osg/ShapeDrawable>
#include<osgDB/readFile>
#include<osg/BlendFunc>#define HIDE_SELECT_BOX 0X0
#define  SHOW_SELECT_BOX ~HIDE_SELECT_BOXclass selectBoxEventHandler : public osgGA::GUIEventHandler
{
public:selectBoxEventHandler(osg::ref_ptr<osg::Camera> spHudCamera){m_spHudCamera = spHudCamera;}
private:virtual bool handle(const osgGA::GUIEventAdapter& ea, osgGA::GUIActionAdapter& aa, osg::Object* obj, osg::NodeVisitor* nv){m_pViewer = (osgViewer::Viewer*)(&aa);if (m_pViewer == nullptr){return false;}auto width = m_pViewer->getCamera()->getViewport()->width();auto height = m_pViewer->getCamera()->getViewport()->height();/* 设置HuD相机为正投影,这样绘制的矩形框和鼠标拖动的框选框大小就一样了且要设置正投影的区域和视图窗体一样大小,因为鼠标可以在窗体任何位置进行框选*/m_spHudCamera->setProjectionMatrix(osg::Matrix::ortho2D(0, width, 0, height));auto eventType = ea.getEventType();switch (eventType){case osgGA::GUIEventAdapter::KEYDOWN:{if ((osgGA::GUIEventAdapter::KEY_Control_L == ea.getKey())|| (osgGA::GUIEventAdapter::KEY_Control_R == ea.getKey())) // Ctrl键被按下{m_ctrlKeyPressed = true;}}break;case osgGA::GUIEventAdapter::KEYUP:{if ((osgGA::GUIEventAdapter::KEY_Control_L == ea.getKey())|| (osgGA::GUIEventAdapter::KEY_Control_R == ea.getKey())) // Ctrl键被按下{m_ctrlKeyPressed = false;}}break;case osgGA::GUIEventAdapter::PUSH:  // 鼠标左键按下{auto buttonMask = ea.getButtonMask();auto bIsMouseBtn = buttonMask & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON;if (bIsMouseBtn){m_fStartPosX = ea.getX();m_fStartPosY = ea.getY();m_bPush = true;}else if (buttonMask & osgGA::GUIEventAdapter::RIGHT_MOUSE_BUTTON) // 鼠标右键按下,则删除选择框{if (m_spRectGeometry != nullptr){m_spRectGeometry->setNodeMask(HIDE_SELECT_BOX);}}}break;case osgGA::GUIEventAdapter::RELEASE:  // 释放鼠标左键{m_bPush = false;}break;case osgGA::GUIEventAdapter::DRAG:    // 拖动鼠标{auto buttonMask = ea.getButtonMask();auto bIsMouseBtn = buttonMask & osgGA::GUIEventAdapter::LEFT_MOUSE_BUTTON;if (bIsMouseBtn && m_ctrlKeyPressed && m_bPush){m_fEndPosX = ea.getX();m_fEndPosY = ea.getY();if (nullptr != m_spRectGeometry){auto pVertArray = (osg::Vec3Array*)m_spRectGeometry->getVertexArray();(*pVertArray)[0].set(m_fStartPosX, m_fStartPosY, 0.0);(*pVertArray)[1].set(m_fStartPosX, m_fEndPosY, 0.0);(*pVertArray)[2].set(m_fEndPosX, m_fEndPosY, 0.0);(*pVertArray)[3].set(m_fEndPosX, m_fStartPosY, 0.0);// m_spRectGeometry->setVertexArray(pVertArray);m_spRectGeometry->dirtyDisplayList(); // 告知底层,外层顶点数据更改了,否则不会用新的坐标绘制矩形m_spRectGeometry->setNodeMask(SHOW_SELECT_BOX);}else{auto spSelectBox = createSelectBox(m_fStartPosX, m_fStartPosY, m_fEndPosX, m_fEndPosY);m_spRectGeometry = spSelectBox->asGeode()->getChild(0)->asGeometry();m_spHudCamera->addChild(spSelectBox);}return true;}}} // end swithreturn  false;}osg::Geode* createSelectBox(float fStartPosX, float fStartPosY, float fEndPosX, float fEndPosY){osg::Geode* pGeode = new osg::Geode();auto pQuardGeomerty = new osg::Geometry();pGeode->addChild(pQuardGeomerty);osg::Vec3Array* pVertArray = new osg::Vec3Array;pVertArray->push_back(osg::Vec3(fStartPosX, fStartPosY, 0.0));pVertArray->push_back(osg::Vec3(fStartPosX, fEndPosY, 0.0));pVertArray->push_back(osg::Vec3(fEndPosX, fEndPosY, 0.0));pVertArray->push_back(osg::Vec3(fEndPosX, fStartPosY, 0.0));pQuardGeomerty->setVertexArray(pVertArray);osg::Vec4Array* pColorArray = new osg::Vec4Array;pColorArray->push_back(osg::Vec4(1.0, 1.0, 1.0, 0.4));/*  pColorArray->push_back(osg::Vec4(1.0, 1.0, 1.0, 0.40));pColorArray->push_back(osg::Vec4(1.0, 1.0, 1.0, 0.40));pColorArray->push_back(osg::Vec4(1.0, 1.0, 1.0, 0.40));*/pQuardGeomerty->setColorArray(pColorArray);//pQuardGeomerty->setColorBinding(osg::Geometry::AttributeBinding::BIND_PER_VERTEX);pQuardGeomerty->setColorBinding(osg::Geometry::AttributeBinding::BIND_PER_PRIMITIVE_SET);pQuardGeomerty->addPrimitiveSet(new osg::DrawArrays(GL_QUADS, 0, 4));pGeode->getOrCreateStateSet()->setMode(GL_LIGHTING, osg::StateAttribute::OFF); // 关闭光照pGeode->getOrCreateStateSet()->setMode(GL_BLEND, osg::StateAttribute::ON); // 开启透明,否则就不能透过选择框看到后面的牛pGeode->addDrawable(pQuardGeomerty);return pGeode;}private:/* 鼠标按下的起始坐标点 */float m_fStartPosX{ 0.0 };float m_fStartPosY{ 0.0 };float m_fEndPosX{ 0.0 };float m_fEndPosY{ 0.0 };bool m_ctrlKeyPressed{ false };             // Ctrl键被按下bool m_bPush{ false };                      // 鼠标左键是否被按下osgViewer::Viewer* m_pViewer{ nullptr };osg::ref_ptr<osg::Camera> m_spHudCamera;  // 用于HUD的相机osg::ref_ptr<osg::Geometry> m_spRectGeometry;      // 矩形框};int main(int argc, char *argv[])
{osgViewer::Viewer viewer;auto cowNode = osgDB::readNodeFile(R"(E:\osg\OpenSceneGraph-Data\cow.osg)");if (nullptr == cowNode){OSG_WARN << "node is null!";return 1;}auto spRoot = new osg::Group();osg::ref_ptr<osg::Camera> spHudCamera = new osg::Camera;spHudCamera->setClearMask(GL_DEPTH_BUFFER_BIT);  // 开启深度缓冲// 设置渲染顺序为后渲染,即始终在其它绘制物体的上面,防止被其它绘制的物体遮挡spHudCamera->setRenderOrder(osg::Camera::RenderOrder::POST_RENDER); spHudCamera->setAllowEventFocus(false);  // 不接受任何焦点事件,即不响应键盘、鼠标事件spHudCamera->setReferenceFrame(osg::Transform::ReferenceFrame::ABSOLUTE_RF); // 设置参考帧为绝对帧spHudCamera->setViewMatrix(osg::Matrix::identity()); // 设置相机视图矩阵为单位矩阵,这样就矩形框选框就不受相机旋转等变换影响spRoot->addChild(cowNode);spRoot->addChild(spHudCamera);viewer.setSceneData(spRoot);viewer.addEventHandler(new selectBoxEventHandler(spHudCamera));return viewer.run();
}

说明

  • 在鼠标拖动坐标改变重新设置矩形框坐标时,记得调用:           
// 告知底层,外层顶点数据更改了,否则不会用新的坐标绘制矩形 
m_spRectGeometry->setVertexArray(pVertArray);

或调用:

 m_spRectGeometry->dirtyDisplayList(); // 告知底层,外层顶点数据更改了,否则不会用新的坐标绘制矩形

在C++中,只要把指针指向的内容改了,也就是立马改了,但在上述代码中如果以为只把顶点数据改了,新矩形就会呈现出来是错误的,不调用上述代码中的某一种,新矩形不会绘制,因为只改了顶点数据,但osg还没执行重绘。

  • 上述采用节点的setNodeMask函数,通过设置节点掩码来实现矩形框的显示或隐藏,其实最好的方法是采用osg::Switch来控制矩形框的显示和隐藏,在此不再详述列出代码,关于这两者的详述,参见:osg利用setNodeMask和Switch隐藏节点用法说明博文。
http://www.zhongyajixie.com/news/22942.html

相关文章:

  • wordpress 3.1seo案例分析100例
  • 个人网站主题百度公司有哪些部门
  • 邢台市住房和城乡建设局网站sem与seo的区别
  • 网站怎么做动态切图新东方在线网上课程
  • 全国疫情最新资讯关键词优化哪家强
  • 拿word如何做网站网站建设的数字化和互联网化
  • 李连杰做的功夫网站semi
  • 加强政府网站建设长春网站建设方案推广
  • 什么作为国内的主要门户网站成都网络推广哪家好
  • 做网站百度新闻源网络推广怎么做
  • 蛋糕网站设计郑州网站公司哪家好
  • 用自己照片做衣服_杯子的是哪个网站武汉百度网站优化公司
  • 武汉建筑公司网站厦门人才网最新招聘信息
  • 莱西网站建设哪家好网站设计
  • 建站平台费用搜索引擎优化的办法有哪些
  • 淘宝上做网站可信吗上海全国关键词排名优化
  • wordpress日主题下载深圳关键词推广整站优化
  • 外贸独立站有哪些平台如何设计一个网页
  • 网站logo如何做清晰seo云优化
  • 个人网站没人访问搜索词
  • 青岛 机械 中企动力提供网站建设微信广告投放推广平台
  • 北京做网站的公司排名做谷歌推广比较好的公司
  • 专门做玉的网站深圳专业seo外包
  • 网站建设行业赚钱么哪个浏览器看黄页最快夸克浏览器
  • 平湖建设局网站成都优化官网公司
  • 学校门户网站作用余姚关键词优化公司
  • java网站开发需要什么软件网站建设费用都选网络
  • 如何获得个人免费网站空间会计培训班多少钱
  • 移动网站开发百度推广登录页面
  • WordPress邮箱验证登录专业网站优化