C++ OpenGL学习笔记(2、绘制橙色三角形绘制、绿色随时间变化的三角形绘制)
相关文章链接
C++ OpenGL学习笔记(1、Hello World空窗口程序)
目录
- 绘制橙色三角形绘制
- 1、主要修改内容有:
- 1.1、在主程序的基础上增加如下3个函数
- 1.2、另外在主程序外面新增3个全局变量
- 1.3、编写两个shader程序文件
- 2、initModel()函数
- 3、initShader函数
- 3.1、vertexShader.glsl文件
- 3.2、fragmentShader.glsl文件
- 3.3、initShader函数代码
- 3、rend函数
- 绿色随时间变化的三角形绘制
- 1.1、fragmentShader.glsl文件修改如下
- 1.2、在rend函数修改如下
- 总代码
- 1、mainl.cpp
- 2、vertexShader.glsl
- 3、fragmentShader.glsl
三角形是最基础的一个面图形,要在一个空的窗口上绘制三角形,就需要在上一节代码基础上进行修改。
绘制橙色三角形绘制
绘制效果
1、主要修改内容有:
1.1、在主程序的基础上增加如下3个函数
1.2、另外在主程序外面新增3个全局变量
如下
1.3、编写两个shader程序文件
vertexShader.glsl文件、fragmentShader.glsl文件
下面一项项的说代码
2、initModel()函数
该函数主要初始化模型,主要是初始化三角形顶点数据,初始化全局变量VAO、VBO
该函数内部流程大概:
0、初始化顶点数组,该数组总共3行,每行都是一个顶点数据,分别表示该点的x、y、z坐标点,所以总共是3个点的数据。
1、创建一个VAO
2、绑定VAO,
3、创建一个VBO,
4、绑定VBO,
5、给VBO分配显存空间,传输数据
6、告诉shader数据解析方式
7、激活锚点
8、给VBO解绑
9、给VAO解绑
该函数完整代码如下
void initModel()
{//构建模型,在模型数据发送GPU,VAO,VBO 在这里完成的//基础数据,三角形顶点float vertices[] = {-0.5f,-0.5f,0.0f,0.5,-0.5,0.0f,0.0f,0.5f,0.0f};glGenVertexArrays(1, &VAO);//创建1个VAOglBindVertexArray(VAO);//绑定VAO//下面初始化VBO,下面的VBO就属于VAO的管理范围,以后绘图直接使用VAO即可glGenBuffers(1, &VBO);//可以同时获取多个VBO的indexglBindBuffer(GL_ARRAY_BUFFER,VBO);//绑定VBOglBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices,GL_STATIC_DRAW);//给GL_ARRAY_BUFFER分配空间,第二个参数:分配多大的空间,第三个参数:从哪里开始读取数据,第四个参数:告诉openGL怎么使用这个数据//下面做锚定点glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//每个顶点包含3个坐标,每个坐标都是float类型,不进行正则化,步长3 * sizeof(float)glEnableVertexAttribArray(0);//激活0号锚点glBindBuffer(GL_ARRAY_BUFFER, 0);//给VBO解绑glBindVertexArray(0);//给VAO解绑}
3、initShader函数
该函数完整形式:void initShader(const char* _vertexPath ,const char* _fragPath );里面两个参数分别是两个shader文件的绝对路径,那么就先把两个shader文件摆出来吧
3.1、vertexShader.glsl文件
该文件为顶点数据处理文件,主要确定顶点位置。代码如下
#version 330 core //版本声明
layout(location = 0) in vec3 aPos;//记得上面在初始化模型里面激活0号锚点的代码吗,这是相对应的void main()
{//gl_Position 是opengl内置全局变量,该变量会在后面进行调用gl_Position = vec4(aPos.x,aPos.y,aPos.z,1.0);
};
里面代码跟普通代码C++代码很相似,每行作用都做了注解,先照抄即可;
3.2、fragmentShader.glsl文件
该文件主要是光栅化显示作用,主要是对顶点数据进行内插,内插后在范围内的进行用指定颜色进行显示出来。
完整代码如下:
#version 330 core
out vec4 FragColor;//任何out定义的变量会被输出到下一步,openGL光栅化的下一步不用管,它是有个管线自动处理的void main()
{FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);//1是白色,0是黑色。橙色RGB为:(1,0.5,0.2)最后一个是alpha通道,默认为1};
注意这里出现了out定义的变量,数据类型是vec4,在shader语言中还有用in、uniform进行定义变量,数据类型可以自定义。区别是:
in定义的变量是由openGL管线中上一步传入过来的,上一步的out变量是下一步的in变量,变量名称不要变化;
uniform定义的变量是由外部C++代码传入进来的,后面可以做一个样例出来,现在先不用管;
管线搞不懂就看下面这张图:
管线顾名思义就是一根像线的管道,在这个管道中只有几个步骤可以进行编辑(填充蓝色的),其他步骤不需要程序员去管的(填充灰色的):
3.3、initShader函数代码
该代码看着比较长,里面实际上只干了几件事情,最终是将shader代码编译链接在全局变量shaderProgram中。
函数流程:
1、读取_vertexPath (vertexShader.glsl)文件到变量_vertexCode中;
2、读取_fragPath (fragmentShader.glsl)文件到变量 _fragCode中;
3、分别编译_vertexCode、 _fragCode代码到_vertexID、_fragID;
4、初始化全局变量shaderProgram,分别将刚刚编译出来的_vertexID、_fragID链接到shaderProgram里面去;
5、分别检查编译是否成功、链接是否成功,最后进行_vertexID、_fragID的释放
void initShader(const char* _vertexPath ,const char* _fragPath )
{//shader写出来,编译出来std::string _vertexCode("");std::string _fragCode("");std::ifstream _vShaderFile;std::ifstream _fShaderFile;_vShaderFile.exceptions(std::ifstream::failbit| std::ifstream::badbit);_fShaderFile.exceptions(std::ifstream::failbit| std::ifstream::badbit);try {_vShaderFile.open(_vertexPath);_fShaderFile.open(_fragPath);std::stringstream _vShaderStream, _fShaderStream;_vShaderStream << _vShaderFile.rdbuf();_fShaderStream << _fShaderFile.rdbuf();_vertexCode = _vShaderStream.str();_fragCode = _fShaderStream.str();}catch (std::ifstream::failure e) {std::string errStr = "rerad shader fail";std::cout << errStr << std::endl;}const char* _vShaderStr = _vertexCode.c_str();const char* _fShaderStr = _fragCode.c_str();//shader的编译链接unsigned int _vertexID = 0,_fragID = 0;char _infoLog[512];//存储错误信息int _successFlag = 0;//是否成功//编译_vertexID = glCreateShader(GL_VERTEX_SHADER);//编译的是VERTEX类型glShaderSource(_vertexID, 1, &_vShaderStr, NULL);//把代码传过去glCompileShader(_vertexID);//编译glGetShaderiv(_vertexID,GL_COMPILE_STATUS,&_successFlag);//获取编译情况如何if (!_successFlag) {//如果编译不成功glGetShaderInfoLog(_vertexID, 512,NULL,_infoLog);std::string errStr(_infoLog);std::cout << errStr << std::endl;}//frag shader _fragID = glCreateShader(GL_FRAGMENT_SHADER);//编译的是FRAGMENT类型glShaderSource(_fragID, 1, &_fShaderStr, NULL);//把代码传过去glCompileShader(_fragID);//编译glGetShaderiv(_fragID, GL_COMPILE_STATUS, &_successFlag);//获取编译情况如何if (!_successFlag) {//如果编译不成功glGetShaderInfoLog(_fragID, 512, NULL, _infoLog);std::string errStr(_infoLog);std::cout << errStr << std::endl;}//链接shaderProgram = glCreateProgram();glAttachShader(shaderProgram,_vertexID);//向program好的加入编译好的glAttachShader(shaderProgram,_fragID);//向program好的加入glLinkProgram(shaderProgram);//开始链接//检查链接是否成功glGetProgramiv(shaderProgram, GL_LINK_STATUS, &_successFlag);if (!_successFlag) {//如果链接不成功glGetProgramInfoLog(shaderProgram, 512, NULL, _infoLog);std::string errStr(_infoLog);std::cout << errStr << std::endl;}//释放glDeleteShader(_vertexID);glDeleteShader(_fragID);}
3、rend函数
该函数是绘制函数,是放在while循环里面的
void rend()
{//渲染函数//每次循环都会调用该函数,直接进行渲染glBindVertexArray(VAO);//使用VAO方式进行绘制glUseProgram(shaderProgram);glDrawArrays(GL_TRIANGLES,0,3);//绘制,从第0个开始画,起作用的是3个glUseProgram(0);
}
编译运行的效果
绿色随时间变化的三角形绘制
该程序是在橙色三角形的基础上进行变种来的,程序逻辑是从外部传入一个随着时间变化的颜色数据即可。
主要修改:
1、fragmentShader.glsl文件中,新增一个uniform定义的颜色变量;
2、在rend函数中新增一个与时间相关的变换函数,该函数输出的值作为绿色波段的颜色值;将新增的绿色波段颜色信息传入到fragmentShader中即可
1.1、fragmentShader.glsl文件修改如下
//外部传参的写法
#version 330 core
out vec4 FragColor;
uniform vec4 MyColor;//通过外部传参进来
void main()
{FragColor = MyColor;//外部传进来的颜色直接传到下一个流程中};
1.2、在rend函数修改如下
void rend()
{//渲染函数//外部传参的写法,将颜色通过外面传入进去===========================================glUseProgram(shaderProgram);//注意这行代码必须提前,否则黑屏,绘制不出来float _time = glfwGetTime();//获取时间,通过时间变换来改变渲染颜色;float _green = sin(_time)*0.5f+0.5f;//动态改变绿色通道的值int _location = glGetUniformLocation(shaderProgram,"MyColor");//获取MyColor变量位置,MyColor即fragmentShader.glsl文件中用uniform修饰的变量glUniform4f(_location, 0.0f, _green, 0.0f, 1.0f);//把颜色传入进去( 0.0f, _green, 0.0f, 1.0f)传入到fragmentShader里面的MyColor变量glBindVertexArray(VAO);//使用VAO方式进行绘制glDrawArrays(GL_TRIANGLES, 0, 3);//绘制,从第0个开始画,起作用的是3个glUseProgram(0);}
运行后,这窗口中三角形随着时间的变化不断循环颜色发生变化,如下图
总代码
总共代码在上次环境配置基础上,修改3个文件:
1、main.cpp
2、vertexShader.glsl
3、fragmentShader.glsl
1、mainl.cpp
/*
三角形绘制基础代码
在这节课介绍三角形绘制的基础方法,也会涉及到基础的shader调用,其中最关键的概念是
VAO、VBO在OpenGL核心模式下的使用及内涵
也会做一个小小的程序结构,让大家方便今后的架构慢慢改进先对vertexShader.glsl 进行顶点变换,再传入fragmentShader.glsl里面插值1、获取VBO的index
2、绑定VBO的index
3、给VBO分配显存空间,传输数据
4、告诉shader数据解析方式
5、激活锚点*/
#include <glad/glad.h>
#include "GLFW/glfw3.h"
#include <iostream>#include <string>
#include <fstream>
#include <sstream>unsigned int VBO = 0;
unsigned int VAO = 0;
unsigned int shaderProgram = 0;void rend()
{//渲染函数每次循环都会调用该函数,直接进行渲染//glBindVertexArray(VAO);//使用VAO方式进行绘制//glUseProgram(shaderProgram);//glDrawArrays(GL_TRIANGLES,0,3);//绘制,从第0个开始画,起作用的是3个//glUseProgram(0);//外部传参的写法,将颜色通过外面传入进去===========================================glUseProgram(shaderProgram);float _time = glfwGetTime();//获取时间,通过时间变换来改变渲染颜色;float _green = sin(_time)*0.5f+0.5f;//动态改变绿色通道的值int _location = glGetUniformLocation(shaderProgram,"MyColor");//获取MyColor变量位置glUniform4f(_location, 0.0f, _green, 0.0f, 1.0f);//把颜色传入进去( 0.0f, _green, 0.0f, 1.0f)传入到fragmentShader里面的MyColor变量glBindVertexArray(VAO);//使用VAO方式进行绘制glDrawArrays(GL_TRIANGLES, 0, 3);//绘制,从第0个开始画,起作用的是3个glUseProgram(0);}void initModel()
{//构建模型,在模型数据发送GPU,VAO,VBO 在这里完成的//基础数据,三角形顶点float vertices[] = {-0.5f,-0.5f,0.0f,0.5,-0.5,0.0f,0.0f,0.5f,0.0f};glGenVertexArrays(1, &VAO);//创建1个VAOglBindVertexArray(VAO);//绑定VAO//下面初始化VBO,下面的VBO就属于VAO的管理范围,以后绘图直接使用VAO即可glGenBuffers(1, &VBO);//可以同时获取多个VBO的indexglBindBuffer(GL_ARRAY_BUFFER,VBO);//绑定VBOglBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices,GL_STATIC_DRAW);//给GL_ARRAY_BUFFER分配空间,第二个参数:分配多大的空间,第三个参数:从哪里开始读取数据,第四个参数:告诉openGL怎么使用这个数据//下面做锚定点glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);//每个顶点包含3个坐标,每个坐标都是float类型,不进行正则化,步长3 * sizeof(float)glEnableVertexAttribArray(0);//激活0号锚点glBindBuffer(GL_ARRAY_BUFFER, 0);//给VBO解绑glBindVertexArray(0);//给VAO解绑}void initShader(const char* _vertexPath ,const char* _fragPath )
{//shader写出来,编译出来std::string _vertexCode("");std::string _fragCode("");std::ifstream _vShaderFile;std::ifstream _fShaderFile;_vShaderFile.exceptions(std::ifstream::failbit| std::ifstream::badbit);_fShaderFile.exceptions(std::ifstream::failbit| std::ifstream::badbit);try {_vShaderFile.open(_vertexPath);_fShaderFile.open(_fragPath);std::stringstream _vShaderStream, _fShaderStream;_vShaderStream << _vShaderFile.rdbuf();_fShaderStream << _fShaderFile.rdbuf();_vertexCode = _vShaderStream.str();_fragCode = _fShaderStream.str();}catch (std::ifstream::failure e) {std::string errStr = "rerad shader fail";std::cout << errStr << std::endl;}const char* _vShaderStr = _vertexCode.c_str();const char* _fShaderStr = _fragCode.c_str();//shader的编译链接unsigned int _vertexID = 0,_fragID = 0;char _infoLog[512];//存储错误信息int _successFlag = 0;//是否成功//编译_vertexID = glCreateShader(GL_VERTEX_SHADER);//编译的是VERTEX类型glShaderSource(_vertexID, 1, &_vShaderStr, NULL);//把代码传过去glCompileShader(_vertexID);//编译glGetShaderiv(_vertexID,GL_COMPILE_STATUS,&_successFlag);//获取编译情况如何if (!_successFlag) {//如果编译不成功glGetShaderInfoLog(_vertexID, 512,NULL,_infoLog);std::string errStr(_infoLog);std::cout << errStr << std::endl;}//frag shader _fragID = glCreateShader(GL_FRAGMENT_SHADER);//编译的是FRAGMENT类型glShaderSource(_fragID, 1, &_fShaderStr, NULL);//把代码传过去glCompileShader(_fragID);//编译glGetShaderiv(_fragID, GL_COMPILE_STATUS, &_successFlag);//获取编译情况如何if (!_successFlag) {//如果编译不成功glGetShaderInfoLog(_fragID, 512, NULL, _infoLog);std::string errStr(_infoLog);std::cout << errStr << std::endl;}//链接shaderProgram = glCreateProgram();glAttachShader(shaderProgram,_vertexID);//向program好的加入编译好的glAttachShader(shaderProgram,_fragID);//向program好的加入glLinkProgram(shaderProgram);//开始链接//检查链接是否成功glGetProgramiv(shaderProgram, GL_LINK_STATUS, &_successFlag);if (!_successFlag) {//如果链接不成功glGetProgramInfoLog(shaderProgram, 512, NULL, _infoLog);std::string errStr(_infoLog);std::cout << errStr << std::endl;}//释放glDeleteShader(_vertexID);glDeleteShader(_fragID);}void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{glViewport(0, 0, width, height);
}void processInput(GLFWwindow *window)
{//检测是否有外部输入if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS){glfwSetWindowShouldClose(window, true);//把关闭状态设置为true}
}int main()
{glfwInit();//初始化上下文环境glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);//要求opengl 3版本以上glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);//设置CORE模式,只能用VAO绘制GLFWwindow* window = glfwCreateWindow(800, 600, "OpenGL Core", NULL, NULL);//创建窗体if (window == NULL){std::cout << "Failed to create GLFW window" << std::endl;glfwTerminate();return -1;}glfwMakeContextCurrent(window);//上下文绑定窗体if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress))//初始化函数指针,为下面函数做准备{std::cout << "Failed to initialize GLAD" << std::endl;return -1;}glViewport(0, 0, 800, 600);//设置需要渲染的视口glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);//设置回调函数initModel();//初始化模型initShader("vertexShader.glsl","fragmentShader.glsl");//初始化shader文件while (!glfwWindowShouldClose(window))//创建的window关掉后就退出while循环{processInput(window);//glClearColor(0.2f, 0.3f, 0.3f, 1.0f);//设置颜色glClear(GL_COLOR_BUFFER_BIT);//用设置的颜色把画布进行清零掉rend();//渲染绘制glfwSwapBuffers(window);glfwPollEvents();}glfwTerminate();std::cout << "Hello World!\n";return 0;
}
2、vertexShader.glsl
#version 330 core
layout(location = 0) in vec3 aPos;
void main()
{//gl_Position 是opengl内置全局变量,该变量会在后面进行调用gl_Position = vec4(aPos.x,aPos.y,aPos.z,1.0);
};
3、fragmentShader.glsl
/*任何out定义的变量会被输出到下一步*/
//#version 330 core
//out vec4 FragColor;
//void main()
//{
// FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
//
//};//外部传参的写法
#version 330 core
out vec4 FragColor;
uniform vec4 MyColor;//通过外部传参进来
void main()
{FragColor = MyColor;//外部传进来的颜色直接传到下一个流程中};
相关文章:

C++ OpenGL学习笔记(2、绘制橙色三角形绘制、绿色随时间变化的三角形绘制)
相关文章链接 C OpenGL学习笔记(1、Hello World空窗口程序) 目录 绘制橙色三角形绘制1、主要修改内容有:1.1、在主程序的基础上增加如下3个函数1.2、另外在主程序外面新增3个全局变量1.3、编写两个shader程序文件 2、initModel()函数3、initS…...
项目搭建+删除(单/批)
一 : 删除没有单独的页面,在列表页面写 二 : 删除在列表的页面 1.删除(单/双)的按钮 ① : 在列表文档就绪函数的ajax里面,成功回调函数追加数据里写删除按钮 注意点 : 删除/修改/回显都是根据id来的,记得传id ② : 批删给批删按钮,定义批删的方法 one : 示例(单删) : //循环追…...
《小米创业思考》
《小米创业思考》是小米创始人雷军对小米创业历程的系统梳理和深度思考,蕴含着许多宝贵的创业经验与智慧,以下是主要内容: 创业初心与梦想 - 源于热爱与使命感:雷军及团队怀着对科技的热爱和让每个人享受科技乐趣的使命感创立小米…...

多种注意力机制详解及其源码
✨✨ 欢迎大家来访Srlua的博文(づ ̄3 ̄)づ╭❤~✨✨ 🌟🌟 欢迎各位亲爱的读者,感谢你们抽出宝贵的时间来阅读我的文章。 我是Srlua小谢,在这里我会分享我的知识和经验。&am…...

VMWare 的克隆操作
零、碎碎念 VMWare 的这个克隆操作很简单,单拎出来成贴的目的是方便后续使用。 一、操作步骤 1.1、在“源”服务器上点右键,选择“管理--克隆” 1.2、选择“虚拟机的当前状态”为基础制作克隆,如下图所示,然后点击“下一页” 1.3、…...

Y3编辑器教程7:界面编辑器
文章目录 一、简介1.1 导航栏1.2 画板1.3 场景界面1.4 控件1.4.1 空节点1.4.2 按钮1.4.3 图片1.4.4 模型1.4.5 文本1.4.6 输入框1.4.7 进度条1.4.8 列表 1.5 元件1.5.1 简介1.5.2 差异说明1.5.3 元件实例的覆盖、还原与禁止操作1.5.4 迷雾控件 1.6 属性1.7 事件(动画…...

「Mac畅玩鸿蒙与硬件45」UI互动应用篇22 - 评分统计工具
本篇将带你实现一个评分统计工具,用户可以对多个选项进行评分。应用会实时更新每个选项的评分结果,并统计平均分。这一功能适合用于问卷调查或评分统计的场景。 关键词 UI互动应用评分统计状态管理数据处理多目标评分 一、功能说明 评分统计工具允许用…...

run postinstall error, please remove node_modules before retry!
下载 node_modules 报错:run postinstall error, please remove node_modules before retry! 原因:node 版本出现错误,我的项目之前是在 12 下运行的。解决方法: 先卸载node_modules清除缓存将node版本切换到12重新下载即可...

详细解读TISAX认证的意义
详细解读TISAX认证的意义,犹如揭开信息安全领域的一颗璀璨明珠,它不仅代表了企业在信息安全管理方面的卓越成就,更是通往全球汽车供应链信任桥梁的关键一环。TISAX,即“Trusted Information Security Assessment Exchange”&#…...

【开源项目】数字孪生轨道~经典开源项目数字孪生智慧轨道——开源工程及源码
飞渡科技数字孪生轨道可视化平台,基于国产数字孪生引擎,结合物联网IOT、大数据、激光雷达等技术,对交通轨道进行超远距、高精度、全天侯的监测,集成轨道交通运营数据,快速准确感知目标,筑牢轨交运营生命线。…...
云原生是什么
云原生是一种构建和运行应用程序的方法,它充分利用了云计算的优势。它不仅仅是指在云上运行应用程序,更重要的是指应用程序的设计、开发、部署和运维方式都充分考虑了云环境的特性,从而能够更好地利用云的弹性、可扩展性和灵活性。 更详细地…...

买卖股票的最佳时机 IV - 困难
************* C topic:188. 买卖股票的最佳时机 IV - 力扣(LeetCode) ************* Stock angin: Still stocks. Intuitively, it feels hard. For once: class Solution { public:int maxProfit(vector<int>& prices) {in…...
linux源码编译php提示:No package ‘oniguruma‘ found
编译遇到缺少Oniguruma开发包,处理办法1 安装epel仓库、安装 Oniguruma 开发包 [rootiZwz98gb9fzslgpnomg3ceZ php-8.1.29]# yum install epel-release [rootiZwz98gb9fzslgpnomg3ceZ php-8.1.29]# yum install oniguruma oniguruma-devel 方法2:去On…...

2024技能大赛Vue流程复现
1. 关于版本的控制 vue/cli 5.0.8vscode 最新下载版本 2. 创建vuecli项目 若没有安装vuecli则可以先安装 npm install -g vue/cli # 默认下载最新版本。vue --version vue -V # 查看版本,两个选一 使用vuecli来创建一个新的vue项目,vs code打开…...

MATLAB截取图像的一部分并保存导出,在itksnap中3D展示
**问题描述:**输入nifti图像,截取图像的一部分并输出,比如截取图像的101010这一块,并导出为nii文件 inputFile D:\aa\dcm\input.nii; % 输入文件路径subsetSize [10 10 10]; % 截取的图像块大小 subsetStart [1 1 1]; % 截取的…...

JMeter配置原件-计数器
一、面临的问题: 由于本人的【函数助手对话框】中counter计数器每次加2,且只显示偶数(如下图所示),因此借助【配置原件-计数器】来实现计数功能。 如果有大佬知道解决方式,麻烦评论区解答一下,谢谢。 二、配置原件-c…...

go面试问题
1 Go的内存逃逸如何分析 go build -gcflags-m main_pointer.go 2 http状态码 300 请求的资源可包括多个位置,相应可返回一个资源特征与地址的列表用于用户终端(例如:浏览器)选择 301 永久移动。请求的资源已被永久的移动到新U…...
springboot 配置Kafka 关闭自启动连接
这里写自定义目录标题 springboot 配置Kafka 关闭自启动连接方法一:使用 ConditionalOnProperty方法二:手动管理Kafka监听器容器方法三:使用 autoStartupfalse结语 springboot 配置Kafka 关闭自启动连接 在Spring Boot应用程序中,…...

selenium工作原理
原文链接:https://blog.csdn.net/weixin_67603503/article/details/143226557 启动浏览器和绑定端口 当你创建一个 WebDriver 实例(如 webdriver.Chrome())时,Selenium 会启动一个新的浏览器实例,并为其分配一个特定的…...

day14-16系统服务管理和ntp和防火墙
一、自有服务概述 服务是一些特定的进程,自有服务就是系统开机后就自动运行的一些进程,一旦客户发出请求,这些进程就自动为他们提供服务,windows系统中,把这些自动运行的进程,称为"服务" window…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

理解 MCP 工作流:使用 Ollama 和 LangChain 构建本地 MCP 客户端
🌟 什么是 MCP? 模型控制协议 (MCP) 是一种创新的协议,旨在无缝连接 AI 模型与应用程序。 MCP 是一个开源协议,它标准化了我们的 LLM 应用程序连接所需工具和数据源并与之协作的方式。 可以把它想象成你的 AI 模型 和想要使用它…...

学校招生小程序源码介绍
基于ThinkPHPFastAdminUniApp开发的学校招生小程序源码,专为学校招生场景量身打造,功能实用且操作便捷。 从技术架构来看,ThinkPHP提供稳定可靠的后台服务,FastAdmin加速开发流程,UniApp则保障小程序在多端有良好的兼…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

OPENCV形态学基础之二腐蚀
一.腐蚀的原理 (图1) 数学表达式:dst(x,y) erode(src(x,y)) min(x,y)src(xx,yy) 腐蚀也是图像形态学的基本功能之一,腐蚀跟膨胀属于反向操作,膨胀是把图像图像变大,而腐蚀就是把图像变小。腐蚀后的图像变小变暗淡。 腐蚀…...

LINUX 69 FTP 客服管理系统 man 5 /etc/vsftpd/vsftpd.conf
FTP 客服管理系统 实现kefu123登录,不允许匿名访问,kefu只能访问/data/kefu目录,不能查看其他目录 创建账号密码 useradd kefu echo 123|passwd -stdin kefu [rootcode caozx26420]# echo 123|passwd --stdin kefu 更改用户 kefu 的密码…...

AI+无人机如何守护濒危物种?YOLOv8实现95%精准识别
【导读】 野生动物监测在理解和保护生态系统中发挥着至关重要的作用。然而,传统的野生动物观察方法往往耗时耗力、成本高昂且范围有限。无人机的出现为野生动物监测提供了有前景的替代方案,能够实现大范围覆盖并远程采集数据。尽管具备这些优势…...

三分算法与DeepSeek辅助证明是单峰函数
前置 单峰函数有唯一的最大值,最大值左侧的数值严格单调递增,最大值右侧的数值严格单调递减。 单谷函数有唯一的最小值,最小值左侧的数值严格单调递减,最小值右侧的数值严格单调递增。 三分的本质 三分和二分一样都是通过不断缩…...