osg - 光照

        OSG全面支持 OpenGL 的光照特性,包括材质属性(material property)、光照属性(light property)和光照模型 (lighting model)。与 OpenGL 相似,OSG中的光源也是不可见的,而非渲染一个灯泡或其他自然形状。同样,光源会创建着色效果,但并不创建阴影,osgShadow 可以用来创建阴影。

1.osg::Light类

        OSG将OpenGL中的 glLight()作了一个 light状态的类封装,用于保存灯光的模式与属性参数信息。osg::Light 类派生自osg::StateAttribute类,继承了对模式与属性参数信息的操作接口。在osg::light类中通过 apply(State&state)函数将灯光的状态参数信息应用到OpenGL 的状态机中。osg::Light的继承关系图如图5-23 所示。

图5-23 osg::Light的继承关系图

        osg::Light类包括的属性参数如下:

  1. int _lightnum;  // 灯光数量  
  2. Vec4 _ambient;  // 环境光颜色  
  3. Vec4 _diffuse;  // 漫光颜色  
  4. Vec4 _specular; // 镜面光颜色  
  5. Vec3 _position; // 光源的位置信息  
  6. Vec3 _direction;// 光源的方向  
  7. float _constant_attenuation; // 常最衰减  
  8. float _linear_attenuation;   // 线性衰减  
  9. float _quadratic_attenuation;// 二次方衰减  
  10. float _spot_exponent; // 指数衰减  
  11. float_spot_cutoff;    // 关闭衰减(spread)  

        上面的参数应该都比较容易理解。OSG 支持最多8个光源,即GL_LIGHTO~GL_LIGHT7,这与读者的OpenGL版本也有关系。

2.osg::LightSource类

        osg::LightSource 类直接继承自 osg::Group。作为一个灯光管理类,继承了 osg::Group 类的管理节点的接口;将灯光作为一个节点可以加入到场景图中进行渲染。继承关系图如图 5-24 所示。

图5-24 osg::LightSource 的继承关系图

            osg::LightSource类中的成员函数为:

  1. void setReferenceFrame(ReferenceFrame rf);// 设置赖引用  

        帧引用包括如下两个枚举变量:

  1. enum ReferenceFrame  
  2. {  
  3.     RELATIVE_RF, // 相对顿引用  
  4.     ABSOLUTE_RF  // 绝对引用  
  5. }  

        设置光源的引用帧时,不是相对于父节点的帧引用,就是相对于绝对坐标的帧,默认的设置为RELATIVE_RF,设置引用为RELATIVE_RF 同样会设置CullingActive 的标志量为开(ON)状态,并且对它的父节点也起作用;否则,对它与它所有的父节点都禁用拣选(Culling),对防止不合适的拣选是必需的,如果绝对光源在场景图的深处将会对拣选的时间有影响,因此,推荐在场景的顶部使用绝对的光源。

 3.场景中使用光源

        在一个场景中添加光源主要包括以下步骤

        (1)指定场景模型的法线。

        (2)允许光照并设置光照状态。

        (3指定光源属性并关联到场景图形

        对于场景中的模型,只有当其中设有单位法线时才会正确地显示光照。当场景中的模型没有指定法线时,可以用前面讲到的osgUtl::SmoothingVisitor自动生成法线。需要注意的是,法向量必须单位化。有时场景中的模型虽然指定了单位法向量,但是光照的计算结果过于明亮或过于暗淡(可能是缩放变换造成的),这时最有效的解决方案是在 StateSet 中允许法线的重放缩模式,代码如下:

  1. osg::StateSet *state = geode->setOrCreateStateSet():  
  2. state->setMode(GL_RESCALE_NORMAL,osg::StateAttribute::ON);  

        与在OpenGL中相同,这一特性可以保证法线在均匀放缩变换时仍然保持单位长度。如果场景中的放缩变换是非均匀的,那么读者可以允许法线归一化模式,以保证法线为单位长度。由于要进行法线的重新放缩,归一化模式往往会耗费大量的时间,编程时要尽量避免。归一化模式的代码如下:

  1. osg::StateSet *state = geode->setOrCreateStateSet():  
  2. state->setMode(GL_NORMALIZE,osg::StateAttribute::ON);  

        要在OSG中获得光照效果,需要允许光照并至少允许一个光源。程序osgviewer 在默认情况下就是这样做的,它在根节点的 StateSet 中已经设置了相应的模式。读者可以在自己的程序中进行相同的设置。下面的代码段用于允许光照并为根节点的 StateSet 允许两个光源(GL_LIGHTO和GL_LIGHT1)

  1. osg::StateSet *state = geode->setOrCreateStateSet():  
  2. state->setMode(GL_LIGHTING,osg::StateAttribute::ON);  
  3. state->setMode(GL_LIGHT0,osg::StateAttribute::ON);  
  4. state->setMode(GL_LIGHT1,osg::StateAttribute::ON);  

        在场景中添加一个光源,可以创建一个osg::Light对象以定义光源参数,然后将osg::Light添加到一个osg::LightSource节点中,并将 LightSource 节点添加到场景图形。osg::LightSource 是一个包含了唯一的Light定义的高效的组节点,而由osg::Light 定义的光源将对整个场景产生影响。下面的代码实现将osg::Light添加到osg::LightSource对象中;

  1. osg::ref_ptr<osg::LightSource> ls = new osg::LightSource;  
  2. ls->setLight(light.get()); 

        在实际生活中,当光照照射到物体上时都会反射等现象,所以,在对光源的设置完成以后需要设置模型的表面材质,第5.4节会讲到,下面先看看关于光照的两个示例。

4.简单光源示例

        简单光源 (osg::LightSource)示例的代码如程序清单5-12 所示:

1.	osg::ref_ptr<osg::Group> createLight(osg::ref_ptr<osg::Node> node) //向场景中添加光源  
2.	{  
3.	    osg::ref_ptr<osg::Group> lightRoot = new osg::Group();  
4.	    lightRoot->addChild(node);  
5.	  
6.	    // 开启光照  
7.	    osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();  
8.	    stateset = lightRoot->getOrCreateStateSet();  
9.	    stateset->setMode(GL_LIGHTING, osg::StateAttribute::ON);  
10.	    stateset->setMode(GL_LIGHT0, osg::StateAttribute::ON);  
11.	  
12.	    // 计算包围盒  
13.	    osg::BoundingSphere bs;  
14.	    node->computeBound();  
15.	    bs = node->getBound();  
16.	  
17.	    // 创建一个Light对象  
18.	    osg::ref_ptr<osg::Light> light = new osg::Light();  
19.	    light->setLightNum(0);     
20.	    light->setDirection(osg::Vec3(0.0f, 0.0f, -1.0f));// 设置方向  
21.	    light->setPosition(osg::Vec4(bs.center().x(), bs.center().y(), bs.center().z() + bs.radius(), 1.0f));// 设置位置   
22.	    light->setAmbient(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));// 设置环境光的颜色   
23.	    light->setDiffuse(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f)); // 设置散射光的颜色      
24.	    light->setConstantAttenuation(1.0f);// 设置恒衰减指数     
25.	    light->setLinearAttenuation(0.0f);  // 设置线形衰减指数    
26.	    light->setQuadraticAttenuation(0.0f);// 设置二次方衰减指数  
27.	  
28.	    // 创建光源  
29.	    osg::ref_ptr<osg::LightSource> lightSource = new osg::LightSource();  
30.	    lightSource->setLight(light.get());  
31.	    lightRoot->addChild(lightSource.get());  
32.	  
33.	    return lightRoot.get();  
34.	}  
35.	  
36.	void lightSource_5_12(const string  &strDataFolder)  
37.	{  
38.	    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();  
39.	    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
40.	    traits->x = 40;  
41.	    traits->y = 40;  
42.	    traits->width = 600;  
43.	    traits->height = 480;  
44.	    traits->windowDecoration = true;  
45.	    traits->doubleBuffer = true;  
46.	    traits->sharedContext = 0;  
47.	  
48.	    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());  
49.	    osg::ref_ptr<osg::Camera> camera = new osg::Camera;  
50.	    camera->setGraphicsContext(gc.get());  
51.	    camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));  
52.	    GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;  
53.	    camera->setDrawBuffer(buffer);  
54.	    camera->setReadBuffer(buffer);  
55.	    viewer->addSlave(camera.get());  
56.	  
57.	    osg::ref_ptr<osg::Group> root = new osg::Group();  
58.	  
59.	    // 读取模型  
60.	    string strDataPath = strDataFolder + "cow.osg";  
61.	    osg::ref_ptr<osg::Node> node = osgDB::readNodeFile(strDataPath);  
62.	  
63.	    // 向场景中添加光源  
64.	    root->addChild(createLight(node.get()));  
65.	  
66.	    // 优化场景数据  
67.	    osgUtil::Optimizer optimizer;  
68.	    optimizer.optimize(root.get());  
69.	  
70.	    viewer->setSceneData(root.get());  
71.	    viewer->realize();  
72.	    viewer->run();  
73.	}  

        运行程序,截图如图5-25 所示

图5-25 简单光源示例裁图

4.聚光灯示例

        聚光灯(SpotLight)示例的代码如程序清单5-13所示:

 

1.	osg::ref_ptr<osg::Image> createSpotLightImage(const osg::Vec4& centerColour,   
2.	    const osg::Vec4& backgroudColour, unsigned int size, float power) // 创建聚光灯纹理的mipmap贴图  
3.	{  
4.	    // 创建Image对象  
5.	    osg::ref_ptr<osg::Image> image = new osg::Image;    
6.	    image->allocateImage(size, size, 1, GL_RGBA, GL_UNSIGNED_BYTE); // 动态分配一个size*size大小的image  
7.	  
8.	    // 填充image  
9.	    // 以中心为原点,颜色逐渐向四周衰减  
10.	    float mid = (float(size) - 1)*0.5f;  
11.	    float div = 2.0f / float(size);  
12.	    for (unsigned int r = 0; r < size; ++r)  
13.	    {  
14.	        unsigned char* ptr = image->data(0, r, 0);  
15.	        for (unsigned int c = 0; c < size; ++c)  
16.	        {  
17.	            float dx = (float(c) - mid)*div;  
18.	            float dy = (float(r) - mid)*div;  
19.	            float r = powf(1.0f - sqrtf(dx*dx + dy*dy), power);  
20.	            if (r < 0.0f) r = 0.0f;  
21.	            osg::Vec4 color = centerColour*r + backgroudColour*(1.0f - r);  
22.	            *ptr++ = (unsigned char)((color[0])*255.0f);  
23.	            *ptr++ = (unsigned char)((color[1])*255.0f);  
24.	            *ptr++ = (unsigned char)((color[2])*255.0f);  
25.	            *ptr++ = (unsigned char)((color[3])*255.0f);  
26.	        }  
27.	    }  
28.	    return image.get();  
29.	}  
30.	  
31.	osg::ref_ptr<osg::StateSet> createSpotLightDecoratorState(unsigned int lightNum,   
32.	    unsigned int textureUnit) // 创建聚光灯状态属性  
33.	{  
34.	    osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet;  
35.	  
36.	    // 开启ID为lightNum的光照  
37.	    stateset->setMode(GL_LIGHT0 + lightNum, osg::StateAttribute::ON);  
38.	  
39.	    // 设置中心的颜色和环境光的颜色  
40.	    osg::Vec4 centerColour(1.0f, 1.0f, 1.0f, 1.0f);  
41.	    osg::Vec4 ambientColour(0.05f, 0.05f, 0.05f, 1.0f);  
42.	  
43.	    // 创建聚光灯纹理  
44.	    osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D();  
45.	    texture->setImage(createSpotLightImage(centerColour, ambientColour, 64, 1.0));  
46.	    texture->setBorderColor(osg::Vec4(ambientColour));  
47.	    texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_BORDER);  
48.	    texture->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP_TO_BORDER);  
49.	    texture->setWrap(osg::Texture::WRAP_R, osg::Texture::CLAMP_TO_BORDER);  
50.	  
51.	    // 打开纹理单元  
52.	    stateset->setTextureAttributeAndModes(textureUnit, texture.get(), osg::StateAttribute::ON);  
53.	  
54.	    // 设置自动生成纹理坐标  
55.	    stateset->setTextureMode(textureUnit, GL_TEXTURE_GEN_S, osg::StateAttribute::ON);  
56.	    stateset->setTextureMode(textureUnit, GL_TEXTURE_GEN_T, osg::StateAttribute::ON);  
57.	    stateset->setTextureMode(textureUnit, GL_TEXTURE_GEN_R, osg::StateAttribute::ON);  
58.	    stateset->setTextureMode(textureUnit, GL_TEXTURE_GEN_Q, osg::StateAttribute::ON);  
59.	  
60.	    return stateset.get();  
61.	}  
62.	  
63.	osg::ref_ptr<osg::Node> createSpotLightNode(const osg::Vec3& position,   
64.	    const osg::Vec3& direction, float angle, unsigned int lightNum,   
65.	    unsigned int textureUnit) // 创建聚光灯节点  
66.	{  
67.	    osg::ref_ptr<osg::Group> group = new osg::Group;  
68.	  
69.	    // 创建光源  
70.	    osg::ref_ptr<osg::LightSource> lightsource = new osg::LightSource;  
71.	    osg::ref_ptr<osg::Light> light = lightsource->getLight();  
72.	    light->setLightNum(lightNum);  
73.	    light->setPosition(osg::Vec4(position, 1.0f));  
74.	    light->setAmbient(osg::Vec4(0.00f, 0.00f, 0.05f, 1.0f));  
75.	    light->setDiffuse(osg::Vec4(1.0f, 1.0f, 1.0f, 1.0f));  
76.	    group->addChild(lightsource);  
77.	  
78.	    // 计算法向量  
79.	    osg::Vec3 up(0.0f, 0.0f, 1.0f);  
80.	    up = (direction ^ up) ^ direction;  
81.	    up.normalize();  
82.	  
83.	    // 创建自动生成纹理坐标节点  
84.	    osg::ref_ptr<osg::TexGenNode> texgenNode = new osg::TexGenNode;     
85.	    texgenNode->setTextureUnit(textureUnit); // 关联纹理单元  
86.	      
87.	    osg::ref_ptr<osg::TexGen> texgen = texgenNode->getTexGen(); // 设置纹理坐标生成器     
88.	    texgen->setMode(osg::TexGen::EYE_LINEAR); // 设置模式为视觉线性     
89.	    texgen->setPlanesFromMatrix(osg::Matrixd::lookAt(position, position + direction, up)*  
90.	        osg::Matrixd::perspective(angle, 1.0, 0.1, 100)); // 从视图中指定参考平面  
91.	    group->addChild(texgenNode.get());  
92.	  
93.	    return group.get();  
94.	}  
95.	  
96.	osg::ref_ptr<osg::AnimationPath> createAnimationPath(const osg::Vec3& center,   
97.	    float radius, double looptime) // 创建动画路径(请参看后面章节的OSG动画)  
98.	{  
99.	    osg::ref_ptr<osg::AnimationPath> animationPath = new osg::AnimationPath;  
100.	    animationPath->setLoopMode(osg::AnimationPath::LOOP);  
101.	  
102.	    int numSamples = 40;  
103.	    float yaw = 0.0f;  
104.	    float yaw_delta = 2.0f*osg::PI / ((float)numSamples - 1.0f);  
105.	    float roll = osg::inDegrees(30.0f);  
106.	  
107.	    double time = 0.0f;  
108.	    double time_delta = looptime / (double)numSamples;  
109.	    for (int i = 0; i < numSamples; ++i)  
110.	    {  
111.	        osg::Vec3 position(center + osg::Vec3(sinf(yaw)*radius, cosf(yaw)*radius, 0.0f));  
112.	        osg::Quat rotation(osg::Quat(roll, osg::Vec3(0.0, 1.0, 0.0))*osg::Quat(-(yaw + osg::inDegrees(90.0f)), osg::Vec3(0.0, 0.0, 1.0)));  
113.	  
114.	        animationPath->insert(time, osg::AnimationPath::ControlPoint(position, rotation));  
115.	  
116.	        yaw += yaw_delta;  
117.	        time += time_delta;  
118.	  
119.	    }  
120.	    return animationPath.get();  
121.	}  
122.	  
123.	osg::ref_ptr<osg::Node> createBase(const string &strDataFolder, const osg::Vec3& center, float radius)// 创建地形平面  
124.	{  
125.	    osg::ref_ptr<osg::Geode> geode = new osg::Geode;  
126.	  
127.	    osg::ref_ptr<osg::StateSet> stateset = new osg::StateSet();  
128.	    string strDataPath = strDataFolder + "Images/lz.rgb";  
129.	    osg::ref_ptr<osg::Image> image = osgDB::readImageFile(strDataPath);  
130.	    if (image.get())  
131.	    {  
132.	        osg::ref_ptr<osg::Texture2D> texture = new osg::Texture2D;  
133.	        texture->setImage(image.get());  
134.	        stateset->setTextureAttributeAndModes(0, texture.get(), osg::StateAttribute::ON);  
135.	    }  
136.	  
137.	    geode->setStateSet(stateset.get());  
138.	  
139.	    osg::ref_ptr<osg::HeightField> grid = new osg::HeightField;  
140.	    grid->allocate(38, 39);  
141.	    grid->setOrigin(center + osg::Vec3(-radius, -radius, 0.0f));  
142.	    grid->setXInterval(radius*2.0f / (float)(38 - 1));  
143.	    grid->setYInterval(radius*2.0f / (float)(39 - 1));  
144.	  
145.	    float minHeight = FLT_MAX;  
146.	    float maxHeight = -FLT_MAX;  
147.	  
148.	  
149.	    unsigned int r;  
150.	    for (r = 0; r < 39; ++r)  
151.	    {  
152.	        for (unsigned int c = 0; c < 38; ++c)  
153.	        {  
154.	            float h = vertex[r + c * 39][2];  
155.	            if (h > maxHeight) maxHeight = h;  
156.	            if (h < minHeight) minHeight = h;  
157.	        }  
158.	    }  
159.	  
160.	    float hieghtScale = radius*0.5f / (maxHeight - minHeight);  
161.	    float hieghtOffset = -(minHeight + maxHeight)*0.5f;  
162.	  
163.	    for (r = 0; r < 39; ++r)  
164.	    {  
165.	        for (unsigned int c = 0; c < 38; ++c)  
166.	        {  
167.	            float h = vertex[r + c * 39][2];  
168.	            grid->setHeight(c, r, (h + hieghtOffset)*hieghtScale);  
169.	        }  
170.	    }  
171.	  
172.	    geode->addDrawable(new osg::ShapeDrawable(grid.get()));  
173.	  
174.	    osg::ref_ptr<osg::Group> group = new osg::Group;  
175.	    group->addChild(geode.get());  
176.	  
177.	    return group.get();  
178.	  
179.	}  
180.	  
181.	osg::ref_ptr<osg::Node> createMovingModel(const string &strDataFolder, const osg::Vec3& center,   
182.	    float radius) // 创建动画模型  
183.	{  
184.	    float animationLength = 10.0f;  
185.	    osg::ref_ptr<osg::AnimationPath> animationPath = createAnimationPath(center, radius, animationLength);  
186.	  
187.	    osg::ref_ptr<osg::Group> model = new osg::Group;  
188.	    string strDataPath = strDataFolder + "cessna.osg";  
189.	    osg::ref_ptr<osg::Node> cessna = osgDB::readNodeFile(strDataPath);  
190.	    if (cessna.get())  
191.	    {  
192.	        const osg::BoundingSphere& bs = cessna->getBound();  
193.	  
194.	        float size = radius / bs.radius()*0.3f;  
195.	        osg::ref_ptr<osg::MatrixTransform> positioned = new osg::MatrixTransform;  
196.	        positioned->setDataVariance(osg::Object::STATIC);  
197.	        positioned->setMatrix(osg::Matrix::translate(-bs.center())*  
198.	            osg::Matrix::scale(size, size, size)*  
199.	            osg::Matrix::rotate(osg::inDegrees(180.0f), 0.0f, 0.0f, 2.0f));  
200.	  
201.	        positioned->addChild(cessna.get());  
202.	  
203.	        osg::ref_ptr<osg::MatrixTransform> xform = new osg::MatrixTransform;  
204.	        xform->setUpdateCallback(new osg::AnimationPathCallback(animationPath, 0.0f, 2.0));  
205.	        xform->addChild(positioned);  
206.	  
207.	        // 添加聚光灯节点  
208.	        xform->addChild(createSpotLightNode(osg::Vec3(0.0f, 0.0f, 0.0f), osg::Vec3(0.0f, 1.0f, -1.0f), 60.0f, 0, 1));  
209.	  
210.	        model->addChild(xform.get());  
211.	    }  
212.	  
213.	    return model.get();  
214.	}  
215.	  
216.	osg::ref_ptr<osg::Node> createModel(const string &strDatafolder) // 创建场景  
217.	{  
218.	    osg::Vec3 center(0.0f, 0.0f, 0.0f);  
219.	    float radius = 100.0f;  
220.	  
221.	    // 创建动画模型  
222.	    osg::ref_ptr<osg::Node> shadower = createMovingModel(strDatafolder, center, radius*0.5f);  
223.	  
224.	    // 创建地形平面  
225.	    osg::ref_ptr<osg::Node> shadowed = createBase(strDatafolder, center - osg::Vec3(0.0f, 0.0f, radius*0.1), radius);  
226.	  
227.	    // 创建场景组节点  
228.	    osg::ref_ptr<osg::Group> root = new osg::Group;     
229.	    root->setStateSet(createSpotLightDecoratorState(0, 1));// 设置状态属性   
230.	    root->addChild(shadower.get()); // 添加子节点  
231.	    root->addChild(shadowed.get());  
232.	  
233.	    return root.get();  
234.	}  
235.	  
236.	void spotLight_5_13(const string &strDatafolder)  
237.	{  
238.	    osg::ref_ptr<osgViewer::Viewer> viewer = new osgViewer::Viewer();  
239.	    osg::ref_ptr<osg::GraphicsContext::Traits> traits = new osg::GraphicsContext::Traits;  
240.	    traits->x = 40;  
241.	    traits->y = 40;  
242.	    traits->width = 600;  
243.	    traits->height = 480;  
244.	    traits->windowDecoration = true;  
245.	    traits->doubleBuffer = true;  
246.	    traits->sharedContext = 0;  
247.	  
248.	    osg::ref_ptr<osg::GraphicsContext> gc = osg::GraphicsContext::createGraphicsContext(traits.get());  
249.	    osg::ref_ptr<osg::Camera> camera = new osg::Camera;  
250.	    camera->setGraphicsContext(gc.get());  
251.	    camera->setViewport(new osg::Viewport(0, 0, traits->width, traits->height));  
252.	    GLenum buffer = traits->doubleBuffer ? GL_BACK : GL_FRONT;  
253.	    camera->setDrawBuffer(buffer);  
254.	    camera->setReadBuffer(buffer);  
255.	    viewer->addSlave(camera.get());  
256.	  
257.	    osg::ref_ptr<osg::Group> root = new osg::Group();  
258.	  
259.	    // 添加场景  
260.	    root->addChild(createModel(strDatafolder));  
261.	  
262.	    // 优化场景数据  
263.	    osgUtil::Optimizer optimizer;  
264.	    optimizer.optimize(root.get());  
265.	  
266.	    viewer->setSceneData(root.get());  
267.	    viewer->realize();  
268.	    viewer->run();  
269.	}  

        运行程序,截图如图5-26所示

图5-26 聚光示例截图

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

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

相关文章

进程的程序替换(exec函数)【Linux】

进程的程序替换详解exec函数【Linux】 程序替换的原理exec系列函数函数理解命令理解&#xff08;助记&#xff09; 关于程序替换中环境变量的解释exec函数之间的关系exec函数的使用execlexeclpexecleexecv 程序替换的原理 进程的程序替换就是让子进程执行新程序&#xff0c; 执…

QT_02 窗口属性、信号槽机制

QT - 窗口属性、信号槽机制 1. 设置窗口属性 窗口设置 1,标题 2,大小 3,固定大小 4,设置图标在 widget.cpp 文件中&#xff1a; //设置窗口大小,此时窗口是可以拉大拉小的 //1参:宽度 //2参:高度 this->resize(800, 600); //设置窗口标题 this->setWindowTitle("…

Docker中的核心概念

1.镜像 Image 一个镜像就代表一个软件。mysql镜像、redis镜像、mq镜像 2.容器 Container 一个镜像运行一次就会生成一个容器&#xff0c;容器就是一个运行的软件服务。 3.远程仓库 Repository 远程仓库用来存储所有软件的镜像&#xff0c;Docker Hub 4.本地仓库 用来存储…

Ubuntu18.04配置静态ip

文章目录 查看网卡名、ip地址、网关切换root用户&#xff0c;进入配置文件配置静态IP 查看网卡名、ip地址、网关 首先查看网卡名、ip地址、网关&#xff0c;找到对应的网卡名并记录其地址 ifconfigroute -n切换root用户&#xff0c;进入配置文件 sudo -icd /etc/netplanvim …

听GPT 讲Rust源代码--compiler(11)

File: rust/compiler/rustc_mir_transform/src/simplify.rs 在Rust源代码中&#xff0c;rust/compiler/rustc_mir_transform/src/simplify.rs文件是Rust编译器中一系列进行MIR&#xff08;中间表示&#xff09;简化的转换的实现。MIR是Rust编译器中用于进行优化和代码生成的中间…

深入理解 BEM:前端开发中的命名约定革命

&#x1f90d; 前端开发工程师&#xff08;主业&#xff09;、技术博主&#xff08;副业&#xff09;、已过CET6 &#x1f368; 阿珊和她的猫_CSDN个人主页 &#x1f560; 牛客高级专题作者、在牛客打造高质量专栏《前端面试必备》 &#x1f35a; 蓝桥云课签约作者、已在蓝桥云…

Python+OpenCV 零基础学习笔记(6):ROI

文章目录 相关链接运行环境前言ROI颜色区域分割颜色通道合并 相关链接 【2022B站最好的OpenCV课程推荐】OpenCV从入门到实战 全套课程 CSDN标题里个括号对应视频的分P OpenCVPython CSDN专栏 Gitee 项目地址 运行环境 Python:3.11.5Anaconda:23.7.4IDE:vscode运行环境&#x…

WebSocket的优点和缺点:一文详解。

WebSocket 的优缺点 WebSocket 协议是一种双向通信协议&#xff0c;它使用单个 TCP 连接实现全双工通信&#xff0c;这使它比传统的 HTTP 协议更有效率。 WebSocket 优点 双向通信&#xff1a; WebSocket 协议支持双向通信&#xff0c;使服务器和客户端之间的通信更加方便和快…

Elasticsearch 中映射参数doc_values 和 fielddata分析比较

一、doc_values 默认情况下&#xff0c;大部分字段是索引的&#xff0c;这样让这些字段可被搜索。倒排索引&#xff08;inverted index&#xff09;允许查询请求在词项列表中查找搜索项&#xff08;search term&#xff09;&#xff0c;并立即获得包含该词项的文档列表。 倒排…

vscode 格式化代码后反而出现红色波浪线格式报错

表现&#xff1a; vscode 代码文件格式化之后&#xff0c;反而出现红色波浪线&#xff0c;提示 应该换行/缩进不正确 等等格式不规范之类的信息。 原因&#xff1a; 因为同时开启了两个格式化插件&#xff0c;且两者的规则有冲突。 就我自己的情况而言&#xff1a;格式化代…

漫谈广告机制设计 | 【预告】万剑归宗:机制设计提高平台广告收入的绝招

读者们好&#xff0c;新年快乐&#xff0c;祝大家新的一年工作顺利&#xff0c;万事如意。 假期更新了两篇文章oCPC实践录 | 以基木鱼为例谈线索类有效转化的设计与智能客服的问题和oCPC实践录 | 目标ROI的出价与转化回传调控算法&#xff0c;欢迎讨论、评论、点赞、分享、转发…

2023年为何YOLO成为最热门视觉检测技术?猫头虎带您揭秘其背后的原因!

博主猫头虎的技术世界 &#x1f31f; 欢迎来到猫头虎的博客 — 探索技术的无限可能&#xff01; 专栏链接&#xff1a; &#x1f517; 精选专栏&#xff1a; 《面试题大全》 — 面试准备的宝典&#xff01;《IDEA开发秘籍》 — 提升你的IDEA技能&#xff01;《100天精通Golang》…

查询运行的java程序线程总数

&#xff08;1&#xff09;方法一 ps -ef|grep java pstree -p pid|wc -l 安装pstree包&#xff0c;yum install psmisc &#xff08;2&#xff09;方法二 top -H -p pid

互联网分布式应用之RabbitMQ

RabbitMQ Java 是第一大编程语言和开发平台。它有助于企业降低成本、缩短开发周期、推动创新以及改善应用服务。如今全球有数百万开发人员运行着超过 51 亿个 Java 虚拟机&#xff0c;Java 仍是企业和开发人员的首选开发平台。 课程内容的介绍 1. RabbitMQ介绍安装 2. Rabbi…

人工智能在金融领域的应用存在的4大挑战

金融服务供应商应该有计划地应对AI面临的难题 金融行业投资人工智能热潮带来有关数据安全和透明度的新问题。由于数据管理实践随着新的 AI 解决方案的引入而不断发展&#xff0c;应对这些新问题以及金融服务领域 AI 面临的其他挑战尤为重要。各组织必须认识到可能面临以下挑战…

2024腾讯云轻量应用服务器详细介绍_轻量全解析

腾讯云轻量应用服务器开箱即用、运维简单的轻量级云服务器&#xff0c;CPU内存带宽配置高并且价格特别便宜&#xff0c;大带宽&#xff0c;但是限制月流量。轻量2核2G3M带宽62元一年、2核2G4M优惠价118元一年&#xff0c;540元三年、2核4G5M带宽218元一年&#xff0c;756元3年、…

指令周期流程图相关题目

已知CPU结构如下图所示&#xff0c;其中包括一个累加器AC、一个状态寄存器和其他几个寄存器。各部分之间的连线表示数据通路&#xff0c;箭头表示信息传递方向。试完成以下工作&#xff1a;①写出图中四个寄存器A、B、C、D的名称和作用&#xff1b;②简述完成指令ADD Y的数据通…

DASS最新论文整理@2023.12

CVPR 2023 论文来源&#xff1a;https://openaccess.thecvf.com/CVPR2023?dayall 1 Planning-oriented Autonomous Driving 面向规划的自动驾驶 (Best papper) 项目地址&#xff1a;https://opendrivelab.github.io/UniAD/ 现代自动驾驶系统的特点是按顺序执行模块化任务…

【Linux】常用的基本命令指令②

前言&#xff1a;前面我们学习了Linux的部分指令&#xff0c;今天我们将接着上次的部分继续将Linux剩余的基本指令. &#x1f496; 博主CSDN主页:卫卫卫的个人主页 &#x1f49e; &#x1f449; 专栏分类:Linux的学习 &#x1f448; &#x1f4af;代码仓库:卫卫周大胖的学习日记…

ROS学习笔记(8)进一步深入了解ROS第二步

0.前提 在上一讲中我提到过该系列是基于宾夕法尼亚大学工程学院的ROS公开课&#xff0c;系列文章将来源于公开课中的课后习题。该系列可以很好的帮助大家更加深入的了解ROS的一些概念。&#xff08;有效面对HR的提问。&#xff09; 1. (C)What is a nodehandle object? Can we…