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

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学习笔记&#xff08;1、Hello World空窗口程序&#xff09; 目录 绘制橙色三角形绘制1、主要修改内容有&#xff1a;1.1、在主程序的基础上增加如下3个函数1.2、另外在主程序外面新增3个全局变量1.3、编写两个shader程序文件 2、initModel()函数3、initS…...

如何创建属于自己的大语言模型:从零开始的指南

如何创建属于自己的大语言模型&#xff1a;从零开始的指南 为什么要创建自己的大语言模型&#xff1f; 随着人工智能的快速发展&#xff0c;大语言模型&#xff08;LLM&#xff09;在各种场景中表现出了卓越的能力&#xff0c;例如文本生成、对话交互和内容总结等。虽然市场上…...

【AIGC安全】CCF-CV企业交流会直播回顾:探寻AI安全治理,共筑可信AI未来

文章目录 一、活动背景&#xff1a;AI技术快速发展与安全治理需求迫切二、论坛内容金耀辉&#xff1a;智能共生时代&#xff1a;平衡生成式AI的创新与风险何延哲&#xff1a;人工智能安全检测评估的逻辑和要点谢洪涛&#xff1a;面向特定人物深度伪造视频的主动防御与被动检测技…...

win11+cuda11x+VS2019安装后没有cuda模板,贫穷版cuda环境

显卡是GTX710&#xff0c;挂在闲鱼200块钱一年多都没卖出去的一款。win11最开始安装了visual studio 2022&#xff0c;不过安装目录自定义&#xff0c;后续安装cuda 11.1.1&#xff0c;这个顺序在各种博客资料都是正确的&#xff0c;先VS&#xff0c;后cuda。但是创建项目也没有…...

四相机设计实现全向视觉感知的开源空中机器人无人机

开源空中机器人 基于深度学习的OmniNxt全向视觉算法OAK-4p-New 全景硬件同步相机 机器人的纯视觉避障定位建图一直是个难题&#xff1a; 系统实现复杂 纯视觉稳定性不高 很难选到实用的视觉传感器 为此多数厂家还是采用激光雷达的定位方案。 OAK-4p-New 为了弥合这一差距…...

越疆科技营收增速放缓:毛利率未恢复,持续亏损下销售费用偏高

《港湾商业观察》施子夫 12月13日&#xff0c;深圳市越疆科技股份有限公司&#xff08;以下简称&#xff0c;越疆科技&#xff0c;02432.HK&#xff09;发布全球发售公告&#xff0c;公司计划全球发售4000万股股份&#xff0c;其中3800万股国际发售&#xff0c;200万股香港公开…...

南城云趣:智能云平台,杜绝电动车充电安全隐患

电动自行车作为绿色低碳出行的主要方式之一,受到无数市民的推崇,而电动自行车数量的急剧上涨,也严重增加小区管理的负担。记者调查发现,目前电动自行车缺乏有效的管理,使得带车或电瓶上楼充电、乱停乱放、车辆容易被盗等安全问题日益突出,给社区消防安全和管理带来严峻的挑战。…...

uniapp对接unipush 1.0 ios/android

简介 实现方法 是uniapp官网推荐的 unipush-v1 文档配置具体看 uni-app官网 配置好了之后 代码实现 前端代码 前端的主要任务是监听 监听到title content 创建消息推送 安卓 可以收到在线消息并且自动弹出消息 IOS 可以监听到在线消息但是需要手动推送 以下代码app初始…...

Vue.js前端框架教程11:Vue监听器watch和watchEffect

文章目录 监听器&#xff08;watchers&#xff09;基本用法deep: trueimmediate: true总结 watchEffect基本用法自动追踪依赖停止监听与 watch 的对比性能优化总结 监听器&#xff08;watchers&#xff09; 在 Vue 中&#xff0c;监听器&#xff08;watchers&#xff09;是一种…...

和数集团针对元宇宙数字身份及资产验证安全性发起挑战

随着时间的推移&#xff0c;元宇宙的发展潜力是无限的。 但与此同时&#xff0c;故事中充斥着疑问、困惑和不安。马克扎克伯格声称人类在未来将生活在虚拟世界中。也许是这样&#xff0c;但元宇宙的应用也面临很多障碍。其中一个领域是安全。对于在元宇宙中发生的任何交易&…...

llama2中的model.py中的结构示意图

参考文章&#xff1a;https://zhuanlan.zhihu.com/p/679640407...

Spring事务管理详解

一、什么是事务管理 事务是一个最小的不可再分的工作单元。 一个事务对应一套完整的业务操作。事务管理是指这些操作要么全部成功执行&#xff0c;要么全部回滚&#xff0c;从而保证数据的一致性和完整性。比如银行转账&#xff0c;需要保证转出和转入是一个原子操作。Spring提…...

被裁20240927 --- 嵌入式硬件开发 前篇

前篇主要介绍一些相关的概念&#xff0c;用于常识扫盲&#xff0c;后篇开始上干货&#xff01; 他捧着一只碗吃过百家的饭 处理器芯片处理器芯片制造商嵌入式处理器芯片制造商国内制造商国外制造商 与意法半导体对标的国产芯片制造商一、中芯国际二、华为海思三、紫光国微四、北…...

CMake的INSTALL FILES和INSTALL DIRECTORY有什么区别

在 CMake 中&#xff0c;install() 命令用于安装构建的目标文件、头文件、库等到指定的目标路径。install(FILES ...) 和 install(DIRECTORY ...) 都是 install() 命令的具体用法&#xff0c;它们的功能和适用场景不同。 以下是两者的详细区别和用法说明&#xff1a; 1. insta…...

提炼关键词的力量:AI驱动下的SEO优化策略

内容概要 在当今数字化营销的环境中&#xff0c;关键词对于提升网站的可见性和流量起着至关重要的作用。企业和个人必须重视有效的关键词策略&#xff0c;以便在竞争激烈的网络市场中脱颖而出。本文将深入探讨如何利用人工智能技术来优化SEO策略&#xff0c;特别是在关键词选择…...

springboot中Controller内文件上传到本地以及阿里云

上传文件的基本操作 <form action"/upload" method"post" enctype"multipart/form-data"> <h1>登录</h1> 姓名&#xff1a;<input type"text" name"username" required><br> 年龄&#xf…...

【MFC】多工具栏如何保存状态

MFC中的工具栏本来只有一个&#xff0c;如果想增加几个工具栏是比较简单&#xff0c;但现在一个重要的问题是&#xff0c;状态无法保存&#xff0c;导致每次打开&#xff0c;工具栏就会出现问题&#xff0c;要么偏移位置要么显示不出。 经过研究&#xff0c;发现是MFC框架中的…...

IDEA搭建SpringBoot,MyBatis,Mysql工程项目

目录 一、前言 二、项目结构 三、初始化项目 四、SpringBoot项目集成Mybatis编写接口 五、代码仓库 一、前言 构建一个基于Spring Boot框架的现代化Web应用程序&#xff0c;以满足[公司/组织名称]对于[业务需求描述]的需求。通过利用Spring Boot简化企业级应用开发的优势&…...

鸿蒙心路旅程:HarmonyOS NEXT 心路旅程:技术、成长与未来

HarmonyOS NEXT 心路旅程&#xff1a;技术、成长与未来 技术的浪潮中&#xff0c;总有一些瞬间让人感到心潮澎湃。作为一名HarmonyOS NEXT开发者&#xff0c;我有幸成为这个时代科技创新的一部分。从最初的接触到深入学习、开发&#xff0c;以及如今规划未来的职业方向&#x…...

【漫话机器学习系列】010.Bagging算法(Bootstrap Aggregating)

Bagging算法&#xff08;Bootstrap Aggregating&#xff09; Bagging&#xff08;Bootstrap Aggregating 的缩写&#xff09;是一种集成学习方法&#xff0c;通过构建多个弱学习器&#xff08;例如决策树&#xff09;并将它们的结果进行平均&#xff08;回归&#xff09;或投票…...

【信息系统项目管理师】高分论文:论信息系统项目的进度管理(人力资源管理系统)

更多内容请见: 备考信息系统项目管理师-专栏介绍和目录 文章目录 论文1、规划进度管理3、排列活动顺序4、估算活动持续时间5、制订进度计划6、控制进度论文 2022年2月,我作为项目经理参与了XX电网公司人力资源管理系统建设项目,该项目是2022年XX电网公司“十三五”信息化规…...

Go web 开发框架 Iris

背景 掌握了 Go 语言的基础后就该开始实践了&#xff0c;编写Web应用首先需要一个 web 开发框架。做框架选型时&#xff0c;处理web请求是基本功能&#xff0c;至于MVC是更进一步需要。现在比较流行的web架构是前后端分离&#xff0c;后端响应RESTful的请求&#xff0c;Iris 能…...

模具生产过程中的标签使用流程图

①NFC芯片嵌入周转筐&#xff0c;通过读卡器读取CK_Label_v3的数据&#xff0c;并将这些信息上传至服务器进行存储&#xff1b; ②服务器随后与客户的WMS&#xff08;仓库管理系统&#xff09;进行交互&#xff0c;记录和同步注塑机的原始数据&#xff1b; ③当周转筐内的模具…...

精准提升:从94.5%到99.4%——目标检测调优全纪录

&#x1f680; 目标检测模型调优过程记录 在进行目标检测模型的训练过程中&#xff0c;我们面对了许多挑战与迭代。从初始模型的训练结果到最终的调优优化&#xff0c;每一步的实验和调整都有其独特的思路和收获。本文记录了我在优化目标检测模型的过程中进行的几次尝试&#…...

【LC】100. 相同的树

题目描述&#xff1a; 给你两棵二叉树的根节点 p 和 q &#xff0c;编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同&#xff0c;并且节点具有相同的值&#xff0c;则认为它们是相同的。 示例 1&#xff1a; 输入&#xff1a;p [1,2,3], q [1,2,3] 输出&…...

Midjourney参数大全

基本参数​ 纵横比&#xff0c;宽高比​ --aspect&#xff0c;或--ar更改生成的纵横比。 混乱​ --chaos <number 0–100>改变结果的变化程度。更高的数值会产生更多不寻常和意想不到的结果。 图像权重​ --iw <0–2>设置相对于原始图像相识度。默认值为 1&a…...

【达梦数据库】获取对象DDL

目录 背景获取表的DDL其他 背景 在排查问题时总会遇到获取对象DDL的问题&#xff0c;因此做以下总结。 获取表的DDL 设置disql工具中显示LONG类型数据的最大长度&#xff0c;避免截断&#xff1a; SET LONG 9999获取DDL SELECT DBMS_METADATA.GET_DDL(TABLE,表名,模式名) …...

51c视觉~合集34

我自己的原文哦~ https://blog.51cto.com/whaosoft/12207162 #图像数据增强库综述 10个强大图像增强工具对比与分析 在深度学习和计算机视觉领域&#xff0c;数据增强已成为提高模型性能和泛化能力的关键技术。本文旨在全面介绍当前广泛使用的图像数据增强库&#xff0c;…...

机动车油耗计算API集成指南

机动车油耗计算API集成指南 引言 在当今社会&#xff0c;随着机动车数量的持续增长和环保意识的不断增强&#xff0c;如何有效管理和降低车辆油耗成为了车主、车队管理者以及交通政策制定者共同关注的问题。为了帮助这些群体更好地理解和优化燃油消耗情况&#xff0c;本接口能…...

正也科技荣获“金石奖2024医药健康互联网优秀服务商奖”

近日&#xff0c;上海正也信息科技有限公司在赛柏蓝第五届医药金石奖颁奖典礼上荣获“金石奖2024医药健康互联网优秀服务商奖”。这一殊荣不仅体现了业内对正也科技在医药信息化领域卓越贡献的高度认可&#xff0c;更是对其持续创新与专业服务的充分肯定。 01 作为深耕医药行…...

Ubuntu搭建ES8集群+加密通讯+https访问

目录 写在前面 一、前期准备 1. 创建用户和用户组 2. 修改limits.conf文件 3. 关闭操作系统swap功能 4. 调整mmap上限 二、安装ES 1.下载ES 2.配置集群间安全访问证书密钥 3.配置elasticsearch.yml 4.修改jvm.options 5.启动ES服务 6.修改密码 7.启用外部ht…...

【2024/12最新】CF罗技鼠标宏分享教程与源码

使用效果&#xff1a; 支持的功能 M4 7发一个点HK417 连点瞬狙炼狱加特林一个圈 下载链接 点击下载...

jmeter 接口性能测试 学习笔记

目录 说明工具准备工具配置jmeter 界面汉化配置汉化步骤汉化结果图 案例1&#xff1a;测试接口接口准备线程组添加线程组配置线程组值线程数&#xff08;Number of Threads&#xff09;Ramp-Up 时间&#xff08;Ramp-Up Period&#xff09;循环次数&#xff08;Loop Count&…...

SpringBoot3整合Knife4j

文章目录 1. 引入依赖2. yml配置文件3. 常用注解3.1 类级别注解3.2 方法级别注解3.3 参数级别注解3.4 模型类注解 4. 访问界面 1. 引入依赖 <!--swagger--> <dependency><groupId>com.github.xiaoymin</groupId><artifactId>knife4j-openapi3-j…...

Dhatim FastExcel 读写 Excel 文件

Dhatim FastExcel 读写 Excel 文件 一、说明1、主要特点2、应用场景 二、使用方法1、引入依赖2、Sheet 数据3、读取 Excel4、写入 Excel 一、说明 Github 地址&#xff1a;Dhatim FastExcel Dhatim FastExcel是一个高性能、轻量级的Java库&#xff0c;专门用于读取和写入Exce…...

精读 84页华为BLM战略规划方法论

这篇文档主要介绍了华为的BLM战略规划方法论&#xff0c;该方法论旨在帮助企业制定战略规划&#xff0c;并确保战略规划的可执行性和有效性。以下是该文档的核心知识点和重点需要关注的内容&#xff1a; 战略规划的定义&#xff1a;战略规划是企业依据企业外部环境和企业自身的…...

如何评估并持续优化AI呼入机器人的使用效果

如何评估并持续优化AI呼入机器人的使用效果 作者&#xff1a;开源呼叫中心FreeIPCC 随着人工智能技术的快速发展&#xff0c;AI呼入机器人在客户服务、技术支持等多个领域得到了广泛应用。这些智能系统不仅提高了工作效率&#xff0c;降低了运营成本&#xff0c;还显著改善了…...

基于.NetCore 的 AI 识别系统的设计与实现

目录 项目背景与概述 技术架构与选型 后端技术 前端技术 系统功能模块 登录注册 数据大屏 练题系统 AI模块 工具箱 个人中心 项目背景与概述 在当今数字化快速发展的时代&#xff0c;人工智能&#xff08;AI&#xff09;技术正逐渐渗透到各个领域&#xff0c;展现出…...

java list 和数组互相转换的一些方法

在Java中&#xff0c;List 和 数组&#xff08;Array&#xff09; 之间的转换是一个常见的操作。由于它们是不同的数据结构&#xff0c;Java提供了一些方法来在它们之间进行转换。我们会从List到数组和数组到List两种情况分别讨论。 1. List 转 数组 假设你有一个 List 类型的…...

【WiFi】WiFi6 5G 802.11ax 最大速率对应表

5GHz 频段 1x1 MIMO 速率 20MHz 信道宽度 MCS 0: 8.6 MbpsMCS 1: 17.2 MbpsMCS 2: 25.8 MbpsMCS 3: 34.4 MbpsMCS 4: 51.6 MbpsMCS 5: 68.8 MbpsMCS 6: 77.4 MbpsMCS 7: 86.0 MbpsMCS 8: 103.2 MbpsMCS 9: 114.7 MbpsMCS 10: 129.0 MbpsMCS 11: 143.4 Mbps 40MHz 信道宽度 …...

智能座舱进阶-应用框架层-Handler分析

首先明确&#xff0c; handler是为了解决单进程内的线程之间的通信问题的。我也需要理解Android系统中进程和线程的概念&#xff0c; APP启动后&#xff0c;会有三四个线程启动起来&#xff0c;其中&#xff0c;有一条mainUITread的线程&#xff0c;专门用来处理UI事件&#xf…...

颜色空间之RGB和HSV互转

参考文档&#xff1a; https://blog.csdn.net/shandianfengfan/article/details/120600453 定点化实现&#xff1a; #define FRAC_BIT 10 // 小数精度 #define MIN3(x,y,z)int min3(int a, int b, int c) {int ret_val a < b ? (a < c ? a : c) : (b < c ? b :…...

程序员之路:编程语言面向过程的特征

以下是面向过程编程语言所具有的一些典型特征&#xff1a; 一、以过程&#xff08;函数、子程序&#xff09;为核心组织代码 强调函数的作用&#xff1a; 在面向过程编程中&#xff0c;函数&#xff08;或子程序等不同语言中的类似概念&#xff09;是代码组织的关键单元。程序…...

matlab的一些时间函数【转】

看到就记下来&#xff0c;感觉挺好玩的。 原文&#xff1a;MATLAB-一些时间函数 - 简书 (jianshu.com) 注明出处了&#xff0c;原文是公开的&#xff0c;应该不算侵权。若有侵权请告知删除谢谢。...

OpenGL —— 2.6.1、绘制一个正方体并贴图渲染颜色(附源码,glfw+glad)

源码效果 C++源码 纹理图片 需下载stb_image.h这个解码图片的库,该库只有一个头文件。 具体代码: vertexShader.glsl #version...

【ETCD】【源码阅读】深入解析 EtcdServer.applyEntries方法

applyEntries方法的主要作用是接收待应用的 Raft 日志条目&#xff0c;并按顺序将其应用到系统中&#xff1b;确保条目的索引连续&#xff0c;避免丢失或重复应用条目。 一、函数完整代码 func (s *EtcdServer) applyEntries(ep *etcdProgress, apply *apply) {if len(apply.…...

【数据分析】数据分析流程优化:从数据采集到可视化的全面指南

目录 引言一、数据采集&#xff1a;高质量数据的起点1.1 数据采集的目标1.2 数据采集的常用方法1.3 数据采集的注意事项 二、数据清洗&#xff1a;确保数据质量2.1 数据清洗的重要性2.2 常见的数据清洗步骤 三、数据分析&#xff1a;从数据中挖掘有价值的洞察3.1 数据分析的目的…...

【华为OD-E卷-字符串重新排序 字符串重新排列 100分(python、java、c++、js、c)】

【华为OD-E卷-字符串重新排序 字符串重新排列 100分&#xff08;python、java、c、js、c&#xff09;】 题目 给定一个字符串s&#xff0c;s包括以空格分隔的若干个单词&#xff0c;请对s进行如下处理后输出&#xff1a; 1、单词内部调整&#xff1a;对每个单词字母重新按字典…...

Mybatis二级缓存

一、二级缓存的概念 MyBatis 的二级缓存是基于命名空间&#xff08;namespace&#xff09;的缓存&#xff0c;它可以被多个 SqlSession 共享。当开启二级缓存后&#xff0c;在一个 SqlSession 中执行的查询结果会被缓存起来&#xff0c;其他 SqlSession 在查询相同的语句&…...

C语言中的宏定义:无参宏与带参宏的详细解析

C语言中的宏定义&#xff1a;无参宏与带参宏的详细解析 在C语言中&#xff0c;宏定义是一种非常强大的预处理功能&#xff0c;通过#define指令可以定义一些常量或者代码片段&#xff0c;用来减少代码重复&#xff0c;提高可读性。本文将详细讲解无参宏与带参宏的使用方法&…...