最长的一帧学习(待补)

news2024/9/21 22:47:57

文章目录

  • 一、osgViewer:: ViewerBase:: frame()
    • 1.osgViewer:: View:: init()
    • 2.osgViewer::Viewer::realize(),窗口和场景的“设置”工作
      • part1 GraphicsContext
        • part1.1 通过阅读osgViewer::View::setUpViewInWindow()了解osg最基础的操作
      • part2 DisplaySettings
      • part3 遍历所得的所有GraphicsContext设备
      • part4 把鼠标焦点转到当前窗口上
      • part5 启动OSG内部定时器并开始计时,设置线程,Compile Contexts
    • 3.正式进入仿真循环当中:advance,eventTraversal,updateTraversal和renderingTraversals
    • 4.osgViewer::Viewer::advance(),循环运行前的准备工作
  • 二、void View::setSceneData(osg::Node* node)中重要的操作

  • 场景图形-SceneGraph;场景子树-Subgraph;节点-Node;摄像机-Camera;渲染器-Renderer;窗口-Window;视口-Viewport;场景-Scene;视图-View;视景器-Viewer;漫游器-Manipulator;访问器-Visitor;回调-Callback;事件-Event;更新-Update;筛选-Cull;绘制-Draw
  • 原文链接:http://bbs.osgchina.org/forum.php?mod=viewthread&tid=509&highlight=OSG%D4%AD%B4%B4%BD%CC%B3%CC%A3%BA%D7%EE%B3%A4%B5%C4%D2%BB%D6%A1

一、osgViewer:: ViewerBase:: frame()

void ViewerBase::frame(double simulationTime)
{
    if (_done) return;

    // OSG_NOTICE<<std::endl<<"CompositeViewer::frame()"<<std::endl<<std::endl;

    if (_firstFrame)
    {
        viewerInit();

        if (!isRealized())
        {
            realize();
        }

        _firstFrame = false;
    }
    advance(simulationTime);

    eventTraversal();
    updateTraversal();
    renderingTraversals();
}

该函数所执行的主要工作如下:

  • 如果这是仿真系统启动后的第一帧,则执行viewerInit();此时如果还没有执行realize()函数,则执行它。
  • 执行advance函数。
  • 执行eventTraversal函数,顾名思义,这个函数将负责处理系统产生的各种事件,诸如鼠标的移动,点击,键盘的响应,窗口的关闭等等,以及摄像机与场景图形的事件回调(EventCallback)。
  • 执行updateTraversal函数,这个函数负责遍历所有的更新回调(UpdateCallback);除此之外,它的另一个重要任务就是负责更新DatabasePager与ImagePager这两个重要的分页数据处理组件。
  • 执行renderingTraversals函数,这里将使用较为复杂的线程处理方法,完成场景的筛选(cull)和绘制(draw)工作。

1.osgViewer:: View:: init()

void View::init()
{
    OSG_INFO<<"View::init()"<<std::endl;

    osg::ref_ptr<osgGA::GUIEventAdapter> initEvent = _eventQueue->createEvent();
    initEvent->setEventType(osgGA::GUIEventAdapter::FRAME);

    if (_cameraManipulator.valid())
    {
        _cameraManipulator->init(*initEvent, *this);
    }
}
  • View::osg::ref_ptrosgGA::EventQueue _eventQueue;储存该视景器的事件队列(osgGA::GUIEventAdapter)
  • 其中createEvent是分配和返回一个新的GUIEventAdapter事件的指针。
  • View::osg::ref_ptrosgGA::CameraManipulator _cameraManipulator为该视景器的操作器的实例,如果希望编写自定义的场景操作器/漫游器,那么覆写并使用osgGA:: MatrixManipulator:: init就可以灵活地初始化自定义漫游器的功能了,它的调用时机就在这里。
  • 其中如果调用的是viewer.run(),没有设置操作器,osg会自动设置一个:
int Viewer::run()
{
    if (!getCameraManipulator() && getCamera()->getAllowEventFocus())
    {
        setCameraManipulator(new osgGA::TrackballManipulator());
    }

    setReleaseContextAtEndOfFrameHint(false);

    return ViewerBase::run();
}

int ViewerBase::run()
{
    if (!isRealized())
    {
        realize();
    }

    unsigned int runTillFrameNumber = osg::UNINITIALIZED_FRAME_NUMBER;
    osg::getEnvVar("OSG_RUN_FRAME_COUNT", runTillFrameNumber);

    while(!done() && (runTillFrameNumber==osg::UNINITIALIZED_FRAME_NUMBER || getViewerFrameStamp()->getFrameNumber()<runTillFrameNumber))
    {
        double minFrameTime = _runMaxFrameRate>0.0 ? 1.0/_runMaxFrameRate : 0.0;
        osg::Timer_t startFrameTick = osg::Timer::instance()->tick();
        if (_runFrameScheme==ON_DEMAND)
        {
            if (checkNeedToDoFrame())
            {
                frame();
            }
            else
            {
                // we don't need to render a frame but we don't want to spin the run loop so make sure the minimum
                // loop time is 1/100th of second, if not otherwise set, so enabling the frame microSleep below to
                // avoid consume excessive CPU resources.
                if (minFrameTime==0.0) minFrameTime=0.01;
            }
        }
        else
        {
            frame();
        }

        // work out if we need to force a sleep to hold back the frame rate
        osg::Timer_t endFrameTick = osg::Timer::instance()->tick();
        double frameTime = osg::Timer::instance()->delta_s(startFrameTick, endFrameTick);
        if (frameTime < minFrameTime) OpenThreads::Thread::microSleep(static_cast<unsigned int>(1000000.0*(minFrameTime-frameTime)));
    }

    return 0;
}

2.osgViewer::Viewer::realize(),窗口和场景的“设置”工作

part1 GraphicsContext

void Viewer::realize(){
Contexts contexts;
getContexts(contexts);}
void Viewer::getContexts(Contexts& contexts, bool onlyValid)
{
    typedef std::set<osg::GraphicsContext*> ContextSet;
    ContextSet contextSet;

    contexts.clear();

    if (_camera.valid() &&
        _camera->getGraphicsContext() &&
        (_camera->getGraphicsContext()->valid() || !onlyValid))
    {
        contextSet.insert(_camera->getGraphicsContext());
        contexts.push_back(_camera->getGraphicsContext());
    }

    for(unsigned int i=0; i<getNumSlaves(); ++i)
    {
        Slave& slave = getSlave(i);
        osg::GraphicsContext* sgc = slave._camera.valid() ? slave._camera->getGraphicsContext() : 0;
        if (sgc && (sgc->valid() || !onlyValid))
        {
            if (contextSet.count(sgc)==0)
            {
                contextSet.insert(sgc);
                contexts.push_back(sgc);
            }
        }
    }
}
  • ViewBase::std::vectorosg::GraphicsContext* Contexts
  • contexts是一个保存了osg::GraphicsContext指针的向量组
  • Viewer::getContexts函数的作用是获取所有的图形上下文,并保存到这个向量组中来。
    首先判断场景的主摄像机_camera是否包含了一个有效的GraphicsContext设备,然后再遍历所有的从摄像机_slaves(一个视景器可以包含一个主摄像级和多个从摄像机),将所有找到的GraphicsContext图形上下文设备记录下来。(其中osg::GraphicsContext*互斥不重复!)
  • 当程序还没有进入仿真循环,且对于osgViewer::Viewer还没有任何的操作之时,系统是不会存在任何图形上下文的;创建一个新的osg::Camera对象也不会为其自动分配图形上下文。但是,图形上下文GraphicsContext却是场景显示的唯一平台,系统有必要在开始渲染之前完成其创建工作。
    假设用户已经在进入仿真循环之前,自行创建了新的Camera摄像机对象,为其分配了自定义的GraphicsContext设备,并将Camera对象传递给视景器,就像osgviewerMFC和osgcamera例子,以及我们在编写与GUI系统嵌合的仿真程序时常做的那样。此时,系统已经不必为图形上下文的创建作任何多余的工作,因为用户不需要更多的窗口来显示自己的场景了。所以就算主摄像机_camera还没有分配GraphicsContext,只要系统中已经存在图形上下文,即可以开始执行仿真程序了
    所以在osgcamera例子中,哪怕有已经有一个主相机(没有gc),但是addsalve了6个带有gc的子相机,也是能正常显示的。
    在这里插入图片描述
    在这里插入图片描述
part1.1 通过阅读osgViewer::View::setUpViewInWindow()了解osg最基础的操作

详见这里!!!
GraphicsContext的创建由平台相关的抽象接口类WindowingSystemInterface负责,对于Win32平台而言,这个类是由GraphicsWindowWin32.cpp的Win32WindowingSystem类具体实现的,它创建的显示窗口设备即osgViewer::GraphicsWindowWin32的实例。

当我们尝试使用createGraphicsContext来创建一个图形设备上下文时,系统返回的实际上是这个函数的值:

ref_ptr<GraphicsContext::WindowingSystemInterface> &wsref = windowingSystemInterfaceRef();
return wsref->createGraphicsContext(traits);

part2 DisplaySettings

void Viewer::realize()
{
。。。
	 // get the display settings that will be active for this viewer
    osg::DisplaySettings* ds = _displaySettings.valid() ? _displaySettings.get() : osg::DisplaySettings::instance().get();
    
    // 获取窗口系统API接口,即GraphicsContext::WindowingSystemInterface的实例
    //  static osg::ref_ptr<WindowingSystemInterfaces>& getWindowingSystemInterfaces()
    osg::GraphicsContext::WindowingSystemInterface* wsi = osg::GraphicsContext::getWindowingSystemInterface();

    // pass on the display settings to the WindowSystemInterface.
    if (wsi && wsi->getDisplaySettings()==0) wsi->setDisplaySettings(ds);

    unsigned int maxTexturePoolSize = ds->getMaxTexturePoolSize();
    unsigned int maxBufferObjectPoolSize = ds->getMaxBufferObjectPoolSize();
}

osg::DisplaySettings类使用单例模式来声明所有这些元素的窗口的唯一实例(一个程序中只能有一个DisplaySettings::instance()对象)。所以我们可以在程序中的任意获取显示设置实例:
DisplaySettings的作用仅仅是保存所有可能在系统显示中用到的数据,这个类本身并不会据此改变任何系统设置和渲染方式
osg::DisplaySettings* ds = osg::DisplaySettings::instance();

  • 主要记录窗口的一些显示设置,例如渲染窗口的OpenGL图像环境。
  • DisplaySettings可以很方便地从系统环境变量或者命令行参数中获取用户对显示设备的设置,详细的调用方法可以参阅DisplaySettings::readEnvironmentalVariables和DisplaySettings::readCommandLine两个函数的内容。
  • 如果希望在用户程序中更改DisplaySettings中的显示设置,请务必在执行视景器的realize函数之前,当然也就是仿真循环开始之前
  • _displayType:显示器类型,默认为MONITOR(监视器),此外还支持POWERWALL(威力墙),REALITY_CENTER(虚拟实境中心)和HEAD_MOUNTED_DISPLAY(头盔显示器)。
  • _stereoMode:立体显示模式,默认为ANAGLYPHIC(互补色),此外还支持QUAD_BUFFER(四方体缓冲),HORIZONTAL_SPLIT(水平分割),VERTICAL_SPLIT(垂直分割),LEFT_EYE(左眼用),RIGHT_EYE(右眼用),HORIZONTAL_INTERLACE(水平交错),VERTICAL_INTERLACE(垂直交错),CHECKERBOARD(棋盘式交错,用于DLP显示器)。
  • _eyeSeparation:双眼的物理距离,默认为0.05。
  • _screenWidth,_screenHeight:屏幕的实际宽度和高度,分别默认设置为0.325和0.26,目前它们影响的仅仅是视图采用透视投影时的宽高比。
  • _screenDistance:人眼到屏幕的距离,默认为0.5。
  • _splitStereoHorizontalEyeMapping:默认为LEFT_EYE_LEFT_VIEWPORT(左眼渲染左视口),也可设为LEFT_EYE_RIGHT_VIEWPORT(左眼渲染右视口)。
  • _splitStereoHorizontalSeparation:左视口和右视口之间的距离(像素数),默认为0。
  • _splitStereoVerticalEyeMapping:默认为LEFT_EYE_TOP_VIEWPORT(左眼渲染顶视口),也可设为LEFT_EYE_BOTTOM_VIEWPORT(左眼渲染底视口)。
  • _splitStereoVerticalSeparation:顶视口和底视口之间的距离(像素数),默认为0。
  • _splitStereoAutoAdjustAspectRatio:默认为true,用于屏幕分割之后对其宽高比进行补偿。
  • _maxNumOfGraphicsContexts:用户程序中最多可用的GraphicsContext(图形设备上下文)数目,默认为32个。
  • _numMultiSamples:多重采样的子像素样本数,默认为0。如果显示卡支持的话,打开多重采样可以大幅改善反走样(anti-aliasing)的效果。
  • _minimumNumberStencilBits(模板缓存的最小位数)
  • 更多具体使用参考这里的Chapter7

part3 遍历所得的所有GraphicsContext设备

void Viewer::realize()
{
。。。
for(Contexts::iterator citr = contexts.begin();
        citr != contexts.end();
        ++citr)
    {
        osg::GraphicsContext* gc = *citr;

        if (ds->getSyncSwapBuffers()) gc->setSwapCallback(new osg::SyncSwapBuffersCallback);

        // set the pool sizes, 0 the default will result in no GL object pools.
        gc->getState()->setMaxTexturePoolSize(maxTexturePoolSize);
        gc->getState()->setMaxBufferObjectPoolSize(maxBufferObjectPoolSize);

        gc->realize();

        if (_realizeOperation.valid() && gc->valid())
        {
            gc->makeCurrent();

            (*_realizeOperation)(gc);

            gc->releaseContext();
        }
    }
}

在这里插入图片描述在这里插入图片描述

_realizeOperation,通过ViewerBase::setRealizeOperation来设置的,其主要作用是在执行realize函数时,顺便完成用户指定的一些工作。您自己的工作内容可以通过继承osg::Operation类,并重载operator()操作符来添加。osgcatch这个妙趣横生的例子(一个傻娃娃接玩具的小游戏)中就使用了setRealizeOperation,主要的作用是为场景中的Drawable几何对象立即编译显示列表(Display List)。

part4 把鼠标焦点转到当前窗口上

当前位置:osgViewer/Viewer.cpp第463行,osgViewer::Viewer::realize()
下面我们再次遍历所有GraphicsContext设备,对于每个GraphicsContext指针gc,判断它是否为GraphicsWindow对象,并执行GraphicsWindow::grabFocusIfPointerInWindow函数。阅读GraphicsWindowWin32类(即GraphicsContext的具体实现者)的同名函数可以发现,这个函数不过是负责把鼠标焦点转到当前窗口上而已。

void Viewer::realize()
{
。。。
// attach contexts to _incrementalCompileOperation if attached.
    if (_incrementalCompileOperation) _incrementalCompileOperation->assignContexts(contexts);

    bool grabFocus = true;
    if (grabFocus)
    {
        for(Contexts::iterator citr = contexts.begin();
            citr != contexts.end();
            ++citr)
        {
            osgViewer::GraphicsWindow* gw = dynamic_cast<osgViewer::GraphicsWindow*>(*citr);
            if (gw)
            {
                gw->grabFocusIfPointerInWindow();
            }
        }
    }
}

part5 启动OSG内部定时器并开始计时,设置线程,Compile Contexts

void Viewer::realize()
{
。。。
// initialize the global timer to be relative to the current time.
    osg::Timer::instance()->setStartTick();

    // pass on the start tick to all the associated event queues
    setStartTick(osg::Timer::instance()->getStartTick());

    // configure threading.
    setUpThreading();

    if (osg::DisplaySettings::instance()->getCompileContextsHint())
    {
        for(unsigned int i=0; i<= osg::GraphicsContext::getMaxContextID(); ++i)
        {
            osg::GraphicsContext* gc = osg::GraphicsContext::getOrCreateCompileContext(i);

            if (gc)
            {
                gc->createGraphicsThread();
                gc->getGraphicsThread()->startThread();
            }
        }
    }
}
  • Viewer::setStartTick函数的工作是找到当前视景器和所有GraphicsContext设备的事件队列_eventQueue,并设定它们的启动时刻为当前时间。
  • ViewerBase::setUpThreading函数……设置线程:
    在这里插入图片描述
  • OSG的视景器包括四种线程模型,可以使用viewer.setThreadingModel进行设置,更多参考这里
    在这里插入图片描述
  • 启用编译上下文Compile Contexts,只需要在调用realize之前执行:osg::DisplaySettings::instance()->setCompileContextsHint(true);
    在这里插入图片描述

3.正式进入仿真循环当中:advance,eventTraversal,updateTraversal和renderingTraversals

4.osgViewer::Viewer::advance(),循环运行前的准备工作

http://bbs.osgchina.org/forum.php?mod=viewthread&tid=519&highlight=OSG%D4%AD%B4%B4%BD%CC%B3%CC%A3%BA%D7%EE%B3%A4%B5%C4%D2%BB%D6%A1

二、void View::setSceneData(osg::Node* node)中重要的操作

void View::setSceneData(osg::Node* node)
{
    if (node==_scene->getSceneData()) return;

    osg::ref_ptr<Scene> scene = Scene::getScene(node);

    if (scene)
    {
        OSG_INFO<<"View::setSceneData() Sharing scene "<<scene.get()<<std::endl;
        _scene = scene;
    }
    else
    {
        if (_scene->referenceCount()!=1)
        {
            // we are not the only reference to the Scene so we cannot reuse it.
            _scene = new Scene;
            OSG_INFO<<"View::setSceneData() Allocating new scene"<<_scene.get()<<std::endl;
        }
        else
        {
            OSG_INFO<<"View::setSceneData() Reusing existing scene"<<_scene.get()<<std::endl;
        }

        _scene->setSceneData(node);
    }

    if (getSceneData())
    {
#if 0
        #if defined(OSG_GLES2_AVAILABLE)
            osgUtil::ShaderGenVisitor sgv;
            getSceneData()->getOrCreateStateSet();
            getSceneData()->accept(sgv);
        #endif
#endif

        // now make sure the scene graph is set up with the correct DataVariance to protect the dynamic elements of
        // the scene graph from being run in parallel.
        osgUtil::Optimizer::StaticObjectDetectionVisitor sodv;
        getSceneData()->accept(sodv);

        // make sure that existing scene graph objects are allocated with thread safe ref/unref
        if (getViewerBase() &&
            getViewerBase()->getThreadingModel()!=ViewerBase::SingleThreaded)
        {
            getSceneData()->setThreadSafeRefUnref(true);
        }

        // update the scene graph so that it has enough GL object buffer memory for the graphics contexts that will be using it.
        // 用户程序中最多可用的GraphicsContext(图形设备上下文)数目,默认为32个
        getSceneData()->resizeGLObjectBuffers(osg::DisplaySettings::instance()->getMaxNumberOfGraphicsContexts());
    }

    computeActiveCoordinateSystemNodePath();

    assignSceneDataToCameras();
}
  • Scene::getScene(node),获取当前视景器对应的osgViewer::Scene对象,也就是场景。一个场景包括了唯一的场景图形根节点,分页数据库(DatabasePager),以及分页图像库(ImagePager)。Viewer视景器对象通常只包括一个Scene场景,而CompositeViewer复合视景器则可能包括多个场景对象。
  • View::assignSceneDataToCameras,这其中包括以下几项工作:
    1、对于场景漫游器_cameraManipulator,执行其setNode函数和home函数,也就是设置漫游器对应于场景图形根节点,并回到其原点位置。不过在我们使用setCameraManipulator函数时也会自动执行同样的操作。
    2、将场景图形赋予主摄像机_camera,同时设置它对应的渲染器(Renderer)的相关函数。
    3、同样将场景图形赋予所有的从摄像机_slaves,并设置每个从摄像机的渲染器(Renderer)。
void View::assignSceneDataToCameras()
{
    // OSG_NOTICE<<"View::assignSceneDataToCameras()"<<std::endl;

    if (_scene.valid() && _scene->getDatabasePager() && getViewerBase())
    {
        _scene->getDatabasePager()->setIncrementalCompileOperation(getViewerBase()->getIncrementalCompileOperation());
    }

    osg::Node* sceneData = _scene.valid() ? _scene->getSceneData() : 0;

    if (_cameraManipulator.valid())
    {
        _cameraManipulator->setNode(sceneData);

        osg::ref_ptr<osgGA::GUIEventAdapter> dummyEvent = _eventQueue->createEvent();

        _cameraManipulator->home(*dummyEvent, *this);
    }

    if (_camera.valid())
    {
        _camera->removeChildren(0,_camera->getNumChildren());
        if (sceneData) _camera->addChild(sceneData);

        Renderer* renderer = dynamic_cast<Renderer*>(_camera->getRenderer());
        if (renderer) renderer->setCompileOnNextDraw(true);

    }

    for(unsigned i=0; i<getNumSlaves(); ++i)
    {
        Slave& slave = getSlave(i);
        if (slave._camera.valid() && slave._useMastersSceneData)
        {
            slave._camera->removeChildren(0,slave._camera->getNumChildren());
            if (sceneData) slave._camera->addChild(sceneData);

            Renderer* renderer = dynamic_cast<Renderer*>(slave._camera->getRenderer());
            if (renderer) renderer->setCompileOnNextDraw(true);
        }
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2033005.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

《机器学习by周志华》学习笔记-决策树-03

1、连续值处理 到目前为止,我们在决策树01、02中仅讨论了基于离散属性来生成决策树,而现实任务中常会遇到连续属性,所以在本章的学习中,我们将会讨论如何在决策树学习中使用连续属性。 1.1、概念 取值范围是连续的实数值或者整数值的属性就是「连续属性」,与离散属性相对…

Java全栈开发知识图谱(概要)

Java全栈开发知识图谱 基础知识 Java基础 语法面向对象编程&#xff08;OOP&#xff09;异常处理集合框架并发编程JVM原理 下列的只是图谱来源与网路 &#xff0c;仅作为学习笔记使用&#xff0c;侵删。 数据结构和算法 常用数据结构&#xff08;数组、链表、栈、队列、树等…

通过提示词越狱解锁学习提示词的新姿势

一、什么是提示词越狱 提示词越狱是一种针对语言模型的攻击方法&#xff0c;攻击者通过设计特定的提示词或查询&#xff0c;诱导模型生成不当或有害的内容。这类攻击通常利用模型的脆弱性&#xff0c;绕过其内置的安全机制。通过巧妙的措辞或特殊的结构&#xff0c;攻击者能够…

【ML】为什么multi-lingual bert 有跨语言的能力?M-BERT有什么特点

【ML】为什么multi-lingual bert 有跨语言的能力&#xff1f; 1. Multi-lingual BERT的跨语言能力解析1.1 什么是Multi-lingual BERT&#xff1f;1.2 为什么Multi-lingual BERT有跨语言的能力&#xff1f;1.3 结论 2. 数据量减少对BERT识别能力的影响及Multi-lingual BERT的跨…

删除git中的.idea

删除git中的.idea 1. 修改 .gitignore 文件内容&#xff0c;添加 .idea echo .idea >> ./gitignore2. 删除本地暂存区的 .idea [git rm命令用于从Git仓库中删除文件或目录&#xff0c; 而--cached选项告诉Git仅删除Git索引中的.idea目录&#xff0c;并不会删除本地文件系…

【大数据】重塑时代的核心技术及其发展历程

&#x1f407;明明跟你说过&#xff1a;个人主页 &#x1f3c5;个人专栏&#xff1a;《大数据前沿&#xff1a;技术与应用并进》&#x1f3c5; &#x1f516;行路有良友&#xff0c;便是天堂&#x1f516; 目录 一、引言 1、什么是大数据 2、大数据技术诞生的背景 二、大…

Java并发编程(七)—ThreadLocal的原理及应用详解

目录 一、ThreadLocal的原理 1、ThreadLocal对象 2、ThreadLocalMap 3、Thread 对象 4、get() 和 set() 方法 5、内存管理 二、ThreadLcoal的应用 三、ThreadLocal扩展问题 四、总结 ThreadLocal 类在 Java 中提供了一种机制&#xff0c;可以在每个线程中存储独立的变…

【Python】基础语法介绍

目录 一、标识符和关键字 二、注释 三、缩进 四、输入和输出 五、字符串操作 六、基本数据类型 七、复合数据类型 7.1 列表 7.2 元组 7.3 字典 7.4 集合 八、数据类型转换 九、运算符 8.1 算术运算符 8.2 比较运算符 8.3 赋值运算符 8.4 位运算符 8.5 逻辑运…

网络编程day1

一、思维导图 网络基础

wordpress全局自适应网址导航整站打包源码,含主题和数据库

wordpress全局自适应网址导航整站打包源码&#xff0c;含主题和数据库。直接恢复就可以使用了。 这个是自适应的布局设计&#xff0c;体验还不错。用网址导航是可以的。 代码免费下载&#xff1a;百度网盘

golang for range time.Ticker 和 time.Timer时间通道使用示例 - 每隔指定时间执行一次,执行指定时长后退出执行

golang中的 ticker和timer时间通道除了可以使用for select case语句来执行外&#xff0c; 还可以使用 for range语句来执行ticker或者timer时间通道。 for range time.Ticker 和 time.Timer时间通道使用示例 下面的示例演示了time.Ticker 和 time.Timer的区别和使用演示。 Ti…

《向量数据库指南》——向量数据库技术积累与商业机会

一豪:Charles提到了一个关键点,就是RAG技术结合模型对非结构化数据的理解和搜索能力,甚至可以很好地架接在传统结构化数据的解决方案中。作为向量数据库的核心技术点,对数据本身特别是非结构化数据的向量化、精炼和压缩,我相信Zilliz等公司有很多独门技巧和技术积累。随着…

UE基础 —— 编辑器界面

菜单栏 UE中每个编辑器都有一个菜单栏&#xff0c;部分菜单会出现在所有编辑器窗口中&#xff0c;如File、Window、Help&#xff0c;其他则是其编辑器特有的&#xff1b; 主工具栏 UE中部分最常用的工具和命令的快捷方式&#xff1b; 1&#xff0c;保存按钮&#xff08;ctrls&a…

NIO线程模型

NIO线程模型主要涉及以下几个方面&#xff1a; 一、基本概念 NIO&#xff08;New Input/Output&#xff09;是Java的一种新的输入输出模型&#xff0c;也被称为非阻塞IO。其核心特点是数据读写操作均是非阻塞的&#xff0c;即在进行读写操作时&#xff0c;若数据未准备好&…

Python第三方库——mrjob的介绍

一、简介 mrjob 是一个强大的 Python 库&#xff0c;它允许开发者以 Pythonic 的方式编写 MapReduce 作业&#xff0c;并在多种环境下运行这些作业&#xff0c;包括本地机器、Hadoop 集群、Amazon Elastic MapReduce (EMR) 和 Google Cloud Dataproc。通过使用 mrjob&#xff…

ARTS Week 37

Algorithm 本周的算法题为 1232. 缀点成线 给定一个数组 coordinates &#xff0c;其中 coordinates[i] [x, y] &#xff0c; [x, y] 表示横坐标为 x、纵坐标为 y 的点。请你来判断&#xff0c;这些点是否在该坐标系中属于同一条直线上。 示例 1:输入&#xff1a;coordinates …

8月9日笔记

8月9日笔记 什么是代理? “代理”通常指的是“网络代理”&#xff0c;它是一种特殊的网络服务&#xff0c;允许一个网络终端&#xff08;一般为客户端&#xff09;通过这个服务与另一个网络终端&#xff08;一般为服务器&#xff09;进行非直接的连接。代理服务器作为中间人…

【中项】系统集成项目管理工程师-第11章 项目范围管理-11.3定义范围

前言&#xff1a;系统集成项目管理工程师专业&#xff0c;现分享一些教材知识点。觉得文章还不错的喜欢点赞收藏的同时帮忙点点关注。 软考同样是国家人社部和工信部组织的国家级考试&#xff0c;全称为“全国计算机与软件专业技术资格&#xff08;水平&#xff09;考试”&…

PHP利用PCRE回溯次数

目录 原理 例子 来一道题&#xff08;2018i春秋圣诞欢乐赛官方WriteUp&#xff09; 利用php弱语言特性解题 利用回溯 原理 对于一串正则表达式来说它匹配了一系列的字符串后自身的正则还没有用完&#xff0c;这个时候就会触发回溯机制&#xff0c;超过回溯次数正则匹配就失…

【代码故事】VSCode知名主题material-theme仓库代码清空

大家好&#xff0c;我是前端之虎陈随易。 这是我的个人网站 https://chensuiyi.me。 出大事了 看到了一篇前端社区开源扛把子 Anthony Fu 的帖子。 经过一番了解&#xff0c;出大事了&#xff01; 知名 VSCode 主题 material-theme 仓库清空了&#xff01; 连带着所有提交…