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

十六、立方体贴图(天空盒)

第一部分 概念:

1) 引用

OpenGL ES 立方体贴图本质上还是纹理映射,是一种 3D 纹理映射。立方体贴图所使的纹理称为立方图纹理,它是由 6 个单独的 2D 纹理组成,每个 2D 纹理是立方图的一个面。

立方图纹理的采样通过一个 3D 向量(s, t, r)作为纹理坐标,这个 3D 向量只作为方向向量使用,OpenGL ES 获取方向向量触碰到立方图表面上的纹理像素作为采样结果。方向向量触碰到立方图表面对应的纹理位置作为采样点,要求立方图的中心必须位于原点。

立方图各个面的指定方法与 2D 纹理基本相同,且每个面必须为正方形(宽度和高度必须相同)。

2)应用

3D纹理跟2D纹理差不多,都是要先生成一个纹理,再绑定,只是2D的是绑定到GL_TEXTURE_2D,而3D的是绑定到**GL_TEXTURE_CUBE_MAP**

GLuint textureID;
glGenTextures(1, &textureID);
glBindTexture(GL_TEXTURE_CUBE_MAP, textureID);

由于立方图包含 6 个纹理,每个面对应一个纹理,需要调用glTexImage2D函数 6 次,OpenGL ES 为立方图提供了 6 个不同的纹理目标,对应立方图的 6 个面,且 6 个纹理目标按顺序依次增 1。

glGenTextures(1, &m_TextureId);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_TextureId);
for (int i = 0; i < m_vcImage.size(); ++i)
{
//6个面的纹理是挨个+1glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,GL_RGBA, m_vcImage[i].width, m_vcImage[i].height, 0, GL_RGBA, GL_UNSIGNED_BYTE,m_vcImage[i].data);LOGD("glTexImage2D %d",i);
}
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);
glBindTexture(GL_TEXTURE_CUBE_MAP, 0);

片段着色器也需要修改,采样器变成了 samplerCube,并且纹理坐标变成了三维方向向量。

#version 300 es
precision mediump float;
in vec3 v_texCoord;
layout(location = 0) out vec4 outColor;
uniform samplerCube s_SkyBox;
void main()
{outColor = texture(s_SkyBox, v_texCoord);
}

第二部分 实践

天空盒内绘制一个立方体,并让立方体的表面反射它周围环境的属性

天空之盒的顶点着色器vSkyBox.vs

#version 300 es
precision mediump float;
layout(location = 0) in vec3 a_position;
uniform mat4 u_MVPMatrix;
out vec3 v_texCoord;
void main()
{gl_Position = u_MVPMatrix * vec4(a_position, 1.0);v_texCoord = a_position;
}

天空之盒的片段着色器fSkyBox.fs

#version 300 es
precision mediump float;
in vec3 v_texCoord;
layout(location = 0) out vec4 outColor;
uniform samplerCube s_SkyBox;//3D纹理为samplerCube类型
void main()
{outColor = texture(s_SkyBox, v_texCoord);
}

立方体的顶点着色器vCube.vs

#version 300 es
precision mediump float;
layout(location = 0) in vec3 a_position;
layout(location = 1) in vec3 a_normal;
uniform mat4 u_MVPMatrix;
uniform mat4 u_ModelMatrix;
out vec3 v_texCoord;
out vec3 v_normal;
void main()
{gl_Position = u_MVPMatrix * vec4(a_position, 1.0);v_normal = mat3(transpose(inverse(u_ModelMatrix))) * a_normal;v_texCoord = vec3(u_ModelMatrix * vec4(a_position, 1.0));
}

立方体的片段着色器fCube.fs

#version 300 es
precision mediump float;
in vec3 v_texCoord;
in vec3 v_normal;
layout(location = 0) out vec4 outColor;
uniform samplerCube s_SkyBox;
uniform vec3 u_cameraPos;
void main()
{float ratio = 1.00 / 1.52;vec3 I = normalize(v_texCoord - u_cameraPos);//反射vec3 R = reflect(I, normalize(v_normal));//折射//vec3 R = refract(I, normalize(v_normal), ratio);outColor = texture(s_SkyBox, R);
}

Skybox.h文件

//
// Created by CreatWall_zhouwen on 2023/5/23.
//#ifndef ELEVENSKYBOX_SKYBOX_H
#define ELEVENSKYBOX_SKYBOX_H
#include <GLES3/gl3.h>
#include <detail/type_mat.hpp>
#include <detail/type_mat4x4.hpp>
#include <vector>
#include <map>
#include "Const.h"
#define MATH_PI 3.1415926535897932384626433832802
class Skybox {
public:Skybox(){m_SamplerLoc = GL_NONE;m_MVPMatLoc = GL_NONE;m_TextureId = GL_NONE;m_SkyBoxVaoId = GL_NONE;m_AngleX = 0;m_AngleY = 0;m_ScaleX = 1.0f;m_ScaleY = 1.0f;m_ModelMatrix = glm::mat4(0.0f);};~Skybox(){};void CreateProgram(const char *ver, const char *frag,const char *curver, const char *curfrag);void Draw();static Skybox* GetInstance();static void DestroyInstance();void OnSurfaceChanged(int width, int height);void UpdateTransformMatrix(float rotateX, float rotateY, float scaleX, float scaleY);void UpdateMVPMatrix(glm::mat4 &mvpMatrix, int angleX, int angleY, float scale, float ratio);void getTexturedata(std::vector<struct ImageTyep> vcImagetemp);
private:GLuint m_TextureId;//纹理IDGLuint m_CubeProgramObj;//立方体工程GLuint m_ProgramObj;//天空盒工程GLuint m_VertexShader;GLuint m_FragmentShader;GLint m_SamplerLoc;//天空盒着色器中uinform变量GLint m_MVPMatLoc;GLint m_CubeSamplerLoc;//立方体着色器中uinform变量GLint m_CubeMVPMatLoc;GLint m_CubeModelMatLoc;GLint m_ViewPosLoc;GLuint m_CubeVaoId;GLuint m_CubeVboId;GLuint m_SkyBoxVaoId;GLuint m_SkyBoxVboId;std::vector<struct ImageTyep> m_vcImage;//存放纹理数据int srceenWidth, srceenHeight;//屏幕宽高glm::mat4 m_MVPMatrix;glm::mat4 m_ModelMatrix;int m_AngleX;int m_AngleY;float m_ScaleX;float m_ScaleY;
};#endif //ELEVENSKYBOX_SKYBOX_H

Skybox.cpp文件

//
// Created by CreatWall_zhouwen on 2023/5/23.
//#include "Skybox.h"
#include "Util.h"
#include "GLUtil.h"
#include <gtc/matrix_transform.hpp>
Skybox* m_pContext = nullptr;
#define TAG "DRAWTEXTURE"
GLfloat cubeVertices[] = {//position           //normal-0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,-0.5f,  0.5f, -0.5f,  0.0f,  0.0f, -1.0f,-0.5f, -0.5f, -0.5f,  0.0f,  0.0f, -1.0f,-0.5f, -0.5f, 0.5f,   0.0f,  0.0f,  1.0f,0.5f, -0.5f, 0.5f,   0.0f,  0.0f,  1.0f,0.5f,  0.5f, 0.5f,   0.0f,  0.0f,  1.0f,0.5f,  0.5f, 0.5f,   0.0f,  0.0f,  1.0f,-0.5f,  0.5f, 0.5f,   0.0f,  0.0f,  1.0f,-0.5f, -0.5f, 0.5f,   0.0f,  0.0f,  1.0f,-0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,-0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,-0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,-0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,-0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,-0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,0.5f,  0.5f, -0.5f,  1.0f,  0.0f,  0.0f,0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,0.5f, -0.5f, -0.5f,  1.0f,  0.0f,  0.0f,0.5f, -0.5f,  0.5f,  1.0f,  0.0f,  0.0f,0.5f,  0.5f,  0.5f,  1.0f,  0.0f,  0.0f,-0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,-0.5f, -0.5f,  0.5f,  0.0f, -1.0f,  0.0f,-0.5f, -0.5f, -0.5f,  0.0f, -1.0f,  0.0f,-0.5f, 0.5f, -0.5f,   0.0f,  1.0f,  0.0f,0.5f, 0.5f, -0.5f,   0.0f,  1.0f,  0.0f,0.5f, 0.5f,  0.5f,   0.0f,  1.0f,  0.0f,0.5f, 0.5f,  0.5f,   0.0f,  1.0f,  0.0f,-0.5f, 0.5f,  0.5f,   0.0f,  1.0f,  0.0f,-0.5f, 0.5f, -0.5f,   0.0f,  1.0f,  0.0f,
};GLfloat skyboxVertices[] = {// Positions-2.0f,  2.0f, -2.0f,-2.0f, -2.0f, -2.0f,2.0f, -2.0f, -2.0f,2.0f, -2.0f, -2.0f,2.0f,  2.0f, -2.0f,-2.0f,  2.0f, -2.0f,-2.0f, -2.0f,  2.0f,-2.0f, -2.0f, -2.0f,-2.0f,  2.0f, -2.0f,-2.0f,  2.0f, -2.0f,-2.0f,  2.0f,  2.0f,-2.0f, -2.0f,  2.0f,2.0f, -2.0f, -2.0f,2.0f, -2.0f,  2.0f,2.0f,  2.0f,  2.0f,2.0f,  2.0f,  2.0f,2.0f,  2.0f, -2.0f,2.0f, -2.0f, -2.0f,-2.0f, -2.0f,  2.0f,-2.0f,  2.0f,  2.0f,2.0f,  2.0f,  2.0f,2.0f,  2.0f,  2.0f,2.0f, -2.0f,  2.0f,-2.0f, -2.0f,  2.0f,-2.0f,  2.0f, -2.0f,2.0f,  2.0f, -2.0f,2.0f,  2.0f,  2.0f,2.0f,  2.0f,  2.0f,-2.0f,  2.0f,  2.0f,-2.0f,  2.0f, -2.0f,-2.0f, -2.0f, -2.0f,-2.0f, -2.0f,  2.0f,2.0f, -2.0f, -2.0f,2.0f, -2.0f, -2.0f,-2.0f, -2.0f,  2.0f,2.0f, -2.0f,  2.0f
};void Skybox::CreateProgram(const char *ver, const char *frag,const char *curver, const char *curfrag) {LOGD("CreateProgram Enter");m_ProgramObj = CreateGLProgram(ver, frag, m_VertexShader, m_FragmentShader);if (m_ProgramObj){m_SamplerLoc = glGetUniformLocation(m_ProgramObj, "s_SkyBox");m_MVPMatLoc = glGetUniformLocation(m_ProgramObj, "u_MVPMatrix");}else{LOGD("SkyBoxSample::Init create m_ProgramObj fail");return;}m_CubeProgramObj = CreateGLProgram(curver, curfrag, m_VertexShader, m_FragmentShader);if (m_CubeProgramObj){m_CubeSamplerLoc = glGetUniformLocation(m_CubeProgramObj, "s_SkyBox");m_CubeMVPMatLoc = glGetUniformLocation(m_CubeProgramObj, "u_MVPMatrix");m_CubeModelMatLoc = glGetUniformLocation(m_CubeProgramObj, "u_ModelMatrix");m_ViewPosLoc = glGetUniformLocation(m_CubeProgramObj, "u_cameraPos");}else{LOGD("SkyBoxSample::Init create m_CubeProgramObj fail");return;}LOGD("CreateProgram Leave");//创建天空盒的VBO 以及绑定VAOglGenBuffers(1, &m_SkyBoxVboId);glBindBuffer(GL_ARRAY_BUFFER, m_SkyBoxVboId);glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), skyboxVertices, GL_STATIC_DRAW);glGenVertexArrays(1, &m_SkyBoxVaoId);//创建VAOglBindVertexArray(m_SkyBoxVaoId);glBindBuffer(GL_ARRAY_BUFFER, m_SkyBoxVboId);//绑定VBOglEnableVertexAttribArray(0);//绑定VBO数据glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (const void *) 0);glBindBuffer(GL_ARRAY_BUFFER, GL_NONE);glBindVertexArray(GL_NONE);//创建立方体的VBO 以及绑定VAOglGenBuffers(1, &m_CubeVboId);glBindBuffer(GL_ARRAY_BUFFER, m_CubeVboId);glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW);glGenVertexArrays(1, &m_CubeVaoId);//创建VAOglBindVertexArray(m_CubeVaoId);glBindBuffer(GL_ARRAY_BUFFER, m_CubeVboId);//绑定VBOglEnableVertexAttribArray(0);//属性O的数据glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (const void *) 0);glEnableVertexAttribArray(1);//属性1的数据 对应顶点着色器的location 1glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3 * sizeof(GLfloat)));glBindBuffer(GL_ARRAY_BUFFER, GL_NONE);glBindVertexArray(GL_NONE);
}void Skybox::Draw() {glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);glClearColor(0.2f, 0.9f, 0.3f, 1.0f);glEnable(GL_DEPTH_TEST);UpdateMVPMatrix(m_MVPMatrix, m_AngleX, m_AngleY, 1.0, (float) srceenWidth / srceenHeight);if (!m_TextureId){//create RGBA textureglGenTextures(1, &m_TextureId);glBindTexture(GL_TEXTURE_CUBE_MAP, m_TextureId);//绑定立体纹理for (int i = 0; i < m_vcImage.size(); ++i){//6个面的纹理是挨个+1glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + i, 0,GL_RGBA, m_vcImage[i].width, m_vcImage[i].height, 0, GL_RGBA, GL_UNSIGNED_BYTE,m_vcImage[i].data);LOGD("glTexImage2D %d",i);}glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE);glBindTexture(GL_TEXTURE_CUBE_MAP, 0);LOGD("sizeof(m_vcImage) / sizeof(ImageTyep) = %d ", sizeof(m_vcImage) / sizeof(ImageTyep));}//画天空盒glUseProgram(m_ProgramObj);glBindVertexArray(m_SkyBoxVaoId);glUniformMatrix4fv(m_MVPMatLoc, 1, GL_FALSE, &m_MVPMatrix[0][0]);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_CUBE_MAP, m_TextureId);glUniform1i(m_SamplerLoc, 0);glDrawArrays(GL_TRIANGLES, 0, 36);//画立方体UpdateMVPMatrix(m_MVPMatrix, m_AngleX, m_AngleY, 0.4f, (float) srceenWidth / srceenHeight);glUseProgram(m_CubeProgramObj);glBindVertexArray(m_CubeVaoId);glUniformMatrix4fv(m_CubeMVPMatLoc, 1, GL_FALSE, &m_MVPMatrix[0][0]);glUniformMatrix4fv(m_CubeModelMatLoc, 1, GL_FALSE, &m_ModelMatrix[0][0]);glUniform3f(m_ViewPosLoc,  0.0f, 0.0f, 1.8f);glActiveTexture(GL_TEXTURE0);glBindTexture(GL_TEXTURE_CUBE_MAP, m_TextureId);glUniform1i(m_CubeSamplerLoc, 0);glDrawArrays(GL_TRIANGLES, 0, 36);}Skybox *Skybox::GetInstance() {if (m_pContext == nullptr){m_pContext = new Skybox();}return m_pContext;
}void Skybox::DestroyInstance() {if (m_pContext){delete m_pContext;m_pContext = nullptr;}
}void Skybox::OnSurfaceChanged(int width, int height) {glViewport(0, 0, width, height);srceenWidth = width;srceenHeight = height;LOGD("OnSurfaceChanged Srceenwidth = %d, Srceenheight = %d, ratio = %f", width,height);
}void Skybox::UpdateTransformMatrix(float rotateX, float rotateY, float scaleX, float scaleY) {m_AngleX = static_cast<int>(rotateX);m_AngleY = static_cast<int>(rotateY);m_ScaleX = scaleX;m_ScaleY = scaleY;
}void Skybox::UpdateMVPMatrix(glm::mat4 &mvpMatrix, int angleX, int angleY, float scale, float ratio) {LOGD("SkyBoxSample::UpdateMVPMatrix angleX = %d, angleY = %d, ratio = %f", angleX,angleY, ratio);angleX = angleX % 360;angleY = angleY % 360;//转化为弧度角float radiansX = static_cast<float>(MATH_PI / 180.0f * angleX);float radiansY = static_cast<float>(MATH_PI / 180.0f * angleY);// Projection matrix//glm::mat4 Projection = glm::ortho(-ratio, ratio, -1.0f, 1.0f, 0.0f, 100.0f);//glm::mat4 Projection = glm::frustum(-ratio, ratio, -1.0f, 1.0f, 4.0f, 100.0f);glm::mat4 Projection = glm::perspective(45.0f, ratio, 0.1f, 100.f);// View matrixglm::mat4 View = glm::lookAt(glm::vec3(0, 0, 1.8), // Camera is at (0,0,1), in World Spaceglm::vec3(0, 0, -1), // and looks at the originglm::vec3(0, 1, 0)  // Head is up (set to 0,-1,0 to look upside-down));// Model matrixglm::mat4 Model = glm::mat4(1.0f);Model = glm::scale(Model, glm::vec3(scale, scale, scale));Model = glm::rotate(Model, radiansX, glm::vec3(1.0f, 0.0f, 0.0f));Model = glm::rotate(Model, radiansY, glm::vec3(0.0f, 1.0f, 0.0f));Model = glm::translate(Model, glm::vec3(0.0f, 0.0f, 0.0f));m_ModelMatrix = Model;mvpMatrix = Projection * View * Model;
}void Skybox::getTexturedata(std::vector<struct ImageTyep> vcImagetemp) {m_vcImage = vcImagetemp;
}

在这里插入图片描述

相关文章:

十六、立方体贴图(天空盒)

第一部分 概念&#xff1a; 1) 引用 OpenGL ES 立方体贴图本质上还是纹理映射&#xff0c;是一种 3D 纹理映射。立方体贴图所使的纹理称为立方图纹理&#xff0c;它是由 6 个单独的 2D 纹理组成&#xff0c;每个 2D 纹理是立方图的一个面。 立方图纹理的采样通过一个 3D 向量…...

UniAD:实现多类别异常检测的统一模型

来源&#xff1a;投稿 作者&#xff1a;Mr.Eraser 编辑&#xff1a;学姐 论文标题&#xff1a;用于多类异常检测的统一模型 论文链接&#xff1a;https://arxiv.org/abs/2206.03687 论文贡献&#xff1a; 提出UniAD&#xff0c;它以一个统一框架完成了多个类别的异常检测。 …...

Java 面试 | tcp ip http https(2023版)

文章目录 HTTP&HTTPS1、Http和Https的区别?2、什么是对称加密与非对称加密3、客户端不断进行请求链接会怎样?DDos(Distributed Denial of Service)攻击?4、GET 与 POST 的区别?5、什么是 HTTP 协议无状态协议?怎么解决Http协议无状态协议?6、Session、Cookie 与 Appl…...

全志V3S嵌入式驱动开发(音频输出和音频录制)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 之前在芯片公司的时候&#xff0c;基本没有看过音频这一块&#xff0c;只知道有个alsa框架这么个知识点。要驱动音频&#xff0c;需要两部分&#…...

使用RP2040自制的树莓派pico—— [2/100] HelloWorld! 和 点亮LED

使用RP2040自制的树莓派pico—— [2/100] HelloWorld! 和 点亮LED 开发环境HelloWorld!闪烁 LED 灯代码 由于比较简单就放在一起写了 开发环境 软件&#xff1a;Thonny HelloWorld! 要想使串口打印HelloWorld&#xff01; 只需要一行代码 print("HelloWorld!")保…...

康耐视In-Sight2800相机的使用

In-Sight2800相机注册分类程序 一、登录相机 二、图像导入 IS相机支持拍摄图像和从文件中导入图像 如选择从文件中导入图像&#xff0c;文件夹选择位置在页面左下方&#xff0c;如下图 三、注册分类器 在检查模块注册分类器&#xff0c;注册图像需要一张一张去学习&#x…...

驱动开发:内核封装WFP防火墙入门

WFP框架是微软推出来替代TDIHOOK传输层驱动接口网络通信的方案&#xff0c;其默认被设计为分层结构&#xff0c;该框架分别提供了用户态与内核态相同的AIP函数&#xff0c;在两种模式下均可以开发防火墙产品&#xff0c;以下代码我实现了一个简单的驱动过滤防火墙。 WFP 框架分…...

python+vue校园快递代取系统的设计与实现3i0v9

开发语言&#xff1a;Python 框架&#xff1a;django/flask Python版本&#xff1a;python3.7.7 数据库&#xff1a;mysql 数据库工具&#xff1a;Navicat 开发软件&#xff1a;PyCharm 本系统名为“基于vue快递代取系统”&#xff0c;系统主要适用于毕业设计&#xff0c;不…...

C 语言详细教程

目录 第一章 C语言基础知识 第二章 数据类型、运算符和表达式 第三章 结构化程序设计 第四章 数组 第五章 函数 第六章 指针 第七章 结构体类型和自定义类型 第八章 编译预处理 第九章 文件 说明&#xff1a;本教程中的代码除一二三个之外&#xff0c;都在https://ligh…...

函数重载与缺省参数

目录 一 缺省参数 缺省参数分半缺省和全缺省。 2&#xff0c;半缺省参数 3&#xff0c;全缺省参数 4.缺省参数的注意事项 二 函数重载 2 .函数重载参数类型不同强调 三 函数名修饰规则 一 缺省参数 1.缺省参数特性(备胎) 缺省参数是指我们定义函数时有给缺省值的参数&#xf…...

线程引入的开销

单线程程序既不存在线程调度&#xff0c;也不存在同步开销&#xff0c;而且不需要使用锁来保证数据结构的一致性。在多个线程的调度和协调过程中都需要一定的性能开销&#xff1a;对于为了提升性能而引入的线程来说&#xff0c;并行带来的性能提升必须超过并发导致的开销。 上下…...

学生成绩管理系统

基于springboot vue实现的学生成绩管理系统 主要模块&#xff1a; 1&#xff09;学生模块&#xff1a;我的成绩、成绩统计、申述管理、修改密码 2&#xff09;教师模块&#xff1a;任务管理、对学生班级任务安排、班级学生的成绩查看、申述管理 3&#xff09;管理员模块&…...

什么是关系模型? 关系模型的基本概念

关系模型由IBM公司研究员Edgar Frank Codd于1970年发表的论文中提出&#xff0c;经过多年的发展&#xff0c;已经成为目前最常用、最重要的模型之一。 在关系模型中有一些基本的概念&#xff0c;具体如下。 (1)关系(Relation)。关系一词与数学领域有关&#xff0c;它是集合基…...

shell编程-02-变量作用域

作用域 局部变量&#xff1a;变量只能在函数内部使用 全局变量&#xff1a;变量可以在当前 Shell 进程中使用 环境变量&#xff1a;变量还可以在子进程中使用 局部变量 函数中定义的变量默认是全局变量&#xff0c;在定义时加上local命令&#xff0c;此时该变量就成了局部变…...

C++服务器框架开发6——日志系统LogFormatter/size_t学习

该专栏记录了在学习一个开发项目的过程中遇到的疑惑和问题。 其教学视频见&#xff1a;[C高级教程]从零开始开发服务器框架(sylar) 上一篇&#xff1a;C服务器框架开发5——日志系统LogAppender/IO类“3种stream”/双感叹号 C服务器框架开发6——日志系统logFormatter/size_t学…...

MYSQL实战45讲笔记--深入浅出索引

深入浅出索引 索引的常见模型 索引模型&#xff1a;是哈希表、有序数组和搜索树。 区别&#xff1a; 哈希表是一种以键 - 值&#xff08;key-value&#xff09;存储数据的结构&#xff0c;我们只要输入待查找的值即 key&#xff0c;就可以找到其对应的值即 Value。哈希的思…...

SpringCloudAlibaba:分布式事务之Seata学习

目录 一、分布式事务基础 &#xff08;一&#xff09;事务 &#xff08;二&#xff09;本地事务 &#xff08;三&#xff09;分布式事务 二、Seata概述 1.Seata 的架构包含: 2.其工作原理为: 3.如果需要在 Spring Boot 应用中使用 Seata 进行分布式事务管理,主要步骤为…...

【MySQL数据库 | 第四篇】SQL通用语法及分类

目录 &#x1f914;SQL通用语法&#xff1a; &#x1f60a;语句&#xff1a; &#x1f60a;注释&#xff1a; &#x1f914;SQL语句分类&#xff1a; &#x1f60a;1.DDL语句&#xff1a; &#x1f60a;2.DML语句&#xff1a; &#x1f60a;3.DQL语言&#xff1a; &…...

Liskov替换原则:用了继承,子类就设计对了吗?

前言 上一篇&#xff0c;我们讲了开放封闭原则&#xff0c;想要让系统符合开放封闭原则&#xff0c;最重要的就是我们要构建起相应的扩展模型&#xff0c;所以&#xff0c;我们要面向接口编程。 而大部分的面向接口编程要依赖于继承实现&#xff0c;继承的重要性不如封装和多…...

腾讯云服务器SA3实例AMD处理器CPU网络带宽性能详解

腾讯云AMD服务器SA3实例CPU采用2.55GHz主频的AMD EPYCTM Milan处理器&#xff0c;睿频3.5GHz&#xff0c;搭载最新一代八通道DDR4&#xff0c;内存计算性能稳定&#xff0c;默认网络优化&#xff0c;最高内网收发能力达1900万pps&#xff0c;最高内网带宽可支持100Gbps。腾讯云…...

在鸿蒙HarmonyOS 5中实现抖音风格的点赞功能

下面我将详细介绍如何使用HarmonyOS SDK在HarmonyOS 5中实现类似抖音的点赞功能&#xff0c;包括动画效果、数据同步和交互优化。 1. 基础点赞功能实现 1.1 创建数据模型 // VideoModel.ets export class VideoModel {id: string "";title: string ""…...

AI Agent与Agentic AI:原理、应用、挑战与未来展望

文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例&#xff1a;使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例&#xff1a;使用OpenAI GPT-3进…...

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility

Cilium动手实验室: 精通之旅---20.Isovalent Enterprise for Cilium: Zero Trust Visibility 1. 实验室环境1.1 实验室环境1.2 小测试 2. The Endor System2.1 部署应用2.2 检查现有策略 3. Cilium 策略实体3.1 创建 allow-all 网络策略3.2 在 Hubble CLI 中验证网络策略源3.3 …...

大语言模型如何处理长文本?常用文本分割技术详解

为什么需要文本分割? 引言:为什么需要文本分割?一、基础文本分割方法1. 按段落分割(Paragraph Splitting)2. 按句子分割(Sentence Splitting)二、高级文本分割策略3. 重叠分割(Sliding Window)4. 递归分割(Recursive Splitting)三、生产级工具推荐5. 使用LangChain的…...

Java多线程实现之Callable接口深度解析

Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

tree 树组件大数据卡顿问题优化

问题背景 项目中有用到树组件用来做文件目录&#xff0c;但是由于这个树组件的节点越来越多&#xff0c;导致页面在滚动这个树组件的时候浏览器就很容易卡死。这种问题基本上都是因为dom节点太多&#xff0c;导致的浏览器卡顿&#xff0c;这里很明显就需要用到虚拟列表的技术&…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

JVM虚拟机:内存结构、垃圾回收、性能优化

1、JVM虚拟机的简介 Java 虚拟机(Java Virtual Machine 简称:JVM)是运行所有 Java 程序的抽象计算机,是 Java 语言的运行环境,实现了 Java 程序的跨平台特性。JVM 屏蔽了与具体操作系统平台相关的信息,使得 Java 程序只需生成在 JVM 上运行的目标代码(字节码),就可以…...

Mysql中select查询语句的执行过程

目录 1、介绍 1.1、组件介绍 1.2、Sql执行顺序 2、执行流程 2.1. 连接与认证 2.2. 查询缓存 2.3. 语法解析&#xff08;Parser&#xff09; 2.4、执行sql 1. 预处理&#xff08;Preprocessor&#xff09; 2. 查询优化器&#xff08;Optimizer&#xff09; 3. 执行器…...