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…...
内存分配函数malloc kmalloc vmalloc
内存分配函数malloc kmalloc vmalloc malloc实现步骤: 1)请求大小调整:首先,malloc 需要调整用户请求的大小,以适应内部数据结构(例如,可能需要存储额外的元数据)。通常,这包括对齐调整,确保分配的内存地址满足特定硬件要求(如对齐到8字节或16字节边界)。 2)空闲…...
Unity3D中Gfx.WaitForPresent优化方案
前言 在Unity中,Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染(即CPU被阻塞),这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案: 对惹,这里有一个游戏开发交流小组&…...
React Native 开发环境搭建(全平台详解)
React Native 开发环境搭建(全平台详解) 在开始使用 React Native 开发移动应用之前,正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南,涵盖 macOS 和 Windows 平台的配置步骤,如何在 Android 和 iOS…...
镜像里切换为普通用户
如果你登录远程虚拟机默认就是 root 用户,但你不希望用 root 权限运行 ns-3(这是对的,ns3 工具会拒绝 root),你可以按以下方法创建一个 非 root 用户账号 并切换到它运行 ns-3。 一次性解决方案:创建非 roo…...
【OSG学习笔记】Day 16: 骨骼动画与蒙皮(osgAnimation)
骨骼动画基础 骨骼动画是 3D 计算机图形中常用的技术,它通过以下两个主要组件实现角色动画。 骨骼系统 (Skeleton):由层级结构的骨头组成,类似于人体骨骼蒙皮 (Mesh Skinning):将模型网格顶点绑定到骨骼上,使骨骼移动…...
在WSL2的Ubuntu镜像中安装Docker
Docker官网链接: https://docs.docker.com/engine/install/ubuntu/ 1、运行以下命令卸载所有冲突的软件包: for pkg in docker.io docker-doc docker-compose docker-compose-v2 podman-docker containerd runc; do sudo apt-get remove $pkg; done2、设置Docker…...
如何在最短时间内提升打ctf(web)的水平?
刚刚刷完2遍 bugku 的 web 题,前来答题。 每个人对刷题理解是不同,有的人是看了writeup就等于刷了,有的人是收藏了writeup就等于刷了,有的人是跟着writeup做了一遍就等于刷了,还有的人是独立思考做了一遍就等于刷了。…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...
A2A JS SDK 完整教程:快速入门指南
目录 什么是 A2A JS SDK?A2A JS 安装与设置A2A JS 核心概念创建你的第一个 A2A JS 代理A2A JS 服务端开发A2A JS 客户端使用A2A JS 高级特性A2A JS 最佳实践A2A JS 故障排除 什么是 A2A JS SDK? A2A JS SDK 是一个专为 JavaScript/TypeScript 开发者设计的强大库ÿ…...
C++课设:简易日历程序(支持传统节假日 + 二十四节气 + 个人纪念日管理)
名人说:路漫漫其修远兮,吾将上下而求索。—— 屈原《离骚》 创作者:Code_流苏(CSDN)(一个喜欢古诗词和编程的Coder😊) 专栏介绍:《编程项目实战》 目录 一、为什么要开发一个日历程序?1. 深入理解时间算法2. 练习面向对象设计3. 学习数据结构应用二、核心算法深度解析…...
