十六、立方体贴图(天空盒)
第一部分 概念:
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;
}
相关文章:
十六、立方体贴图(天空盒)
第一部分 概念: 1) 引用 OpenGL ES 立方体贴图本质上还是纹理映射,是一种 3D 纹理映射。立方体贴图所使的纹理称为立方图纹理,它是由 6 个单独的 2D 纹理组成,每个 2D 纹理是立方图的一个面。 立方图纹理的采样通过一个 3D 向量…...
UniAD:实现多类别异常检测的统一模型
来源:投稿 作者:Mr.Eraser 编辑:学姐 论文标题:用于多类异常检测的统一模型 论文链接:https://arxiv.org/abs/2206.03687 论文贡献: 提出UniAD,它以一个统一框架完成了多个类别的异常检测。 …...
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嵌入式驱动开发(音频输出和音频录制)
【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing 163.com】 之前在芯片公司的时候,基本没有看过音频这一块,只知道有个alsa框架这么个知识点。要驱动音频,需要两部分&#…...
使用RP2040自制的树莓派pico—— [2/100] HelloWorld! 和 点亮LED
使用RP2040自制的树莓派pico—— [2/100] HelloWorld! 和 点亮LED 开发环境HelloWorld!闪烁 LED 灯代码 由于比较简单就放在一起写了 开发环境 软件:Thonny HelloWorld! 要想使串口打印HelloWorld! 只需要一行代码 print("HelloWorld!")保…...
康耐视In-Sight2800相机的使用
In-Sight2800相机注册分类程序 一、登录相机 二、图像导入 IS相机支持拍摄图像和从文件中导入图像 如选择从文件中导入图像,文件夹选择位置在页面左下方,如下图 三、注册分类器 在检查模块注册分类器,注册图像需要一张一张去学习&#x…...
驱动开发:内核封装WFP防火墙入门
WFP框架是微软推出来替代TDIHOOK传输层驱动接口网络通信的方案,其默认被设计为分层结构,该框架分别提供了用户态与内核态相同的AIP函数,在两种模式下均可以开发防火墙产品,以下代码我实现了一个简单的驱动过滤防火墙。 WFP 框架分…...
python+vue校园快递代取系统的设计与实现3i0v9
开发语言:Python 框架:django/flask Python版本:python3.7.7 数据库:mysql 数据库工具:Navicat 开发软件:PyCharm 本系统名为“基于vue快递代取系统”,系统主要适用于毕业设计,不…...
C 语言详细教程
目录 第一章 C语言基础知识 第二章 数据类型、运算符和表达式 第三章 结构化程序设计 第四章 数组 第五章 函数 第六章 指针 第七章 结构体类型和自定义类型 第八章 编译预处理 第九章 文件 说明:本教程中的代码除一二三个之外,都在https://ligh…...
函数重载与缺省参数
目录 一 缺省参数 缺省参数分半缺省和全缺省。 2,半缺省参数 3,全缺省参数 4.缺省参数的注意事项 二 函数重载 2 .函数重载参数类型不同强调 三 函数名修饰规则 一 缺省参数 1.缺省参数特性(备胎) 缺省参数是指我们定义函数时有给缺省值的参数…...
线程引入的开销
单线程程序既不存在线程调度,也不存在同步开销,而且不需要使用锁来保证数据结构的一致性。在多个线程的调度和协调过程中都需要一定的性能开销:对于为了提升性能而引入的线程来说,并行带来的性能提升必须超过并发导致的开销。 上下…...
学生成绩管理系统
基于springboot vue实现的学生成绩管理系统 主要模块: 1)学生模块:我的成绩、成绩统计、申述管理、修改密码 2)教师模块:任务管理、对学生班级任务安排、班级学生的成绩查看、申述管理 3)管理员模块&…...
什么是关系模型? 关系模型的基本概念
关系模型由IBM公司研究员Edgar Frank Codd于1970年发表的论文中提出,经过多年的发展,已经成为目前最常用、最重要的模型之一。 在关系模型中有一些基本的概念,具体如下。 (1)关系(Relation)。关系一词与数学领域有关,它是集合基…...
shell编程-02-变量作用域
作用域 局部变量:变量只能在函数内部使用 全局变量:变量可以在当前 Shell 进程中使用 环境变量:变量还可以在子进程中使用 局部变量 函数中定义的变量默认是全局变量,在定义时加上local命令,此时该变量就成了局部变…...
C++服务器框架开发6——日志系统LogFormatter/size_t学习
该专栏记录了在学习一个开发项目的过程中遇到的疑惑和问题。 其教学视频见:[C高级教程]从零开始开发服务器框架(sylar) 上一篇:C服务器框架开发5——日志系统LogAppender/IO类“3种stream”/双感叹号 C服务器框架开发6——日志系统logFormatter/size_t学…...
MYSQL实战45讲笔记--深入浅出索引
深入浅出索引 索引的常见模型 索引模型:是哈希表、有序数组和搜索树。 区别: 哈希表是一种以键 - 值(key-value)存储数据的结构,我们只要输入待查找的值即 key,就可以找到其对应的值即 Value。哈希的思…...
SpringCloudAlibaba:分布式事务之Seata学习
目录 一、分布式事务基础 (一)事务 (二)本地事务 (三)分布式事务 二、Seata概述 1.Seata 的架构包含: 2.其工作原理为: 3.如果需要在 Spring Boot 应用中使用 Seata 进行分布式事务管理,主要步骤为…...
【MySQL数据库 | 第四篇】SQL通用语法及分类
目录 🤔SQL通用语法: 😊语句: 😊注释: 🤔SQL语句分类: 😊1.DDL语句: 😊2.DML语句: 😊3.DQL语言: &…...
Liskov替换原则:用了继承,子类就设计对了吗?
前言 上一篇,我们讲了开放封闭原则,想要让系统符合开放封闭原则,最重要的就是我们要构建起相应的扩展模型,所以,我们要面向接口编程。 而大部分的面向接口编程要依赖于继承实现,继承的重要性不如封装和多…...
腾讯云服务器SA3实例AMD处理器CPU网络带宽性能详解
腾讯云AMD服务器SA3实例CPU采用2.55GHz主频的AMD EPYCTM Milan处理器,睿频3.5GHz,搭载最新一代八通道DDR4,内存计算性能稳定,默认网络优化,最高内网收发能力达1900万pps,最高内网带宽可支持100Gbps。腾讯云…...
接口测试常用测试点
接口测试是测试系统组件间接口的一种测试。接口测试主要用于检测外部系统与系统之间以及内部各个子系统之间的交互点。测试的重点是要检查数据的交换,传递和控制管理过程,以及系统间的相互逻辑依赖关系等。 测试的策略: 接口测试也是属于功…...
Unity之OpenXR+XR Interaction Toolkit接入HTC Vive解决手柄无法使用的问题
前言 随着Unity版本的不断进化,VR的接口逐渐统一,现在大部分的VR项目都开始使用OpenXR开发了。基于OpenXR,我们可以快速适配HTC,Pico,Oculus,等等设备。 今天我们要说的问题就是,当我们按照官方的标准流程配置完OpenXR后(参考:Unity之OpenXR+XR Interaction Toolkit…...
AC变DC220V变5V小家电电源芯片-AH8652、AH8669
Q: 什么是AH8652和AH8669电源芯片? A: AH8652和AH8669都是AC变DC的电源芯片,适用于将输入的交流电压(220V)转换为5V直流电压输出,用于小家电的电源模块等应用。 AC变DC220V变5V小家电电源芯片-AH8669 Q: AH8652和AH8669的最大输…...
深度学习笔记之循环神经网络(九)GRU的反向传播过程
深度学习笔记之循环神经网络——GRU的反向传播过程 引言回顾: GRU \text{GRU} GRU的前馈计算过程场景设计 反向传播过程 T \mathcal T T时刻的反向传播过程 T − 1 \mathcal T - 1 T−1时刻的反向传播路径 T − 2 \mathcal T - 2 T−2时刻的反向传播路径 总结 引言 …...
ISFP型人格的性格缺陷和心理问题分析
ISFP人格的特征:性格敏感、为人善良、是具有有创造力的人格类型。他们喜欢追求内心的感受和情感,注重自由、个性和独立。ISFP性人格偏于内向,善于自省,对情绪敏感度高,同理心强。 每种人格类型的都有各自的优势和不足…...
HTML <dir> 标签
HTML5 中不支持 <dir> 标签在 HTML 4 中用于列出目录标题。 实例 目录列表: <dir><li>HTML</li><li>XHTML</li><li>CSS</li> </dir>浏览器支持 IEFirefoxChromeSafariOpera 所有主流浏览器都支持 <…...
leetcode 621. 任务调度器
题目链接:leetcode 621 1.题目 给你一个用字符数组 tasks 表示的 CPU 需要执行的任务列表。其中每个字母表示一种不同种类的任务。任务可以以任意顺序执行,并且每个任务都可以在 1 个单位时间内执行完。在任何一个单位时间,CPU 可以完成一个…...
线程任务的取消
如果外部代码能在某个操作正常完成之前将其置入“完成”状态,那么这个操作就可以称为可取消的(Cancellable)。取消某个操作的原因很多: 用户请求取消。用户点击图形界面程序中的“取消”按钮,或者通过管理接口来发出取消请求,例如JMX (Java …...
在线聊天项目
人事管理项目-在线聊天 后端接口实现前端实现 在线聊天是一个为了方便HR进行快速沟通提高工作效率而开发的功能,考虑到一个公司中的HR并不多,并发量不大,因此这里直接使用最基本的WebSocket来完成该功能。 后端接口实现 要使用WebSocket&…...
动态规划-硬币排成线
动态规划-硬币排成线 1 描述2 样例2.1 样例 1:2.2 样例 2:2.3 样例 3: 3 算法解题思路及实现3.1 算法解题分析3.1.1 确定状态3.1.2 转移方程3.1.3 初始条件和边界情况3.1.4 计算顺序 3.2 算法实现3.2.1 动态规划常规实现3.2.2 动态规划滚动数组 该题是lintcode的第394题&#x…...
怎样用js做网站轮播图/济南seo整站优化招商电话
软件测试自学报班都可以,但是不要报那种只学到功能测试的班。 无论是自学还是培训首先要了解自己的是否适合学习?其次要知道软件测试应该学什么?有没有一个标准?最后要开始做计划、找资料,了解一些别人的学习经验&…...
常用wap网站开发工具 手机网站制作软件/关键词优化的作用
题库来源:安全生产模拟考试一点通公众号小程序 G1工业锅炉司炉(新版)考试内容是安全生产模拟考试一点通总题库中随机出的一套G1工业锅炉司炉(新版)模拟考试系统,在公众号安全生产模拟考试一点通上点击G1工…...
岳麓区做网站/花西子网络营销策划方案
Rainbow的asp.net 2.0版本还没有正式发布,从他的代码库可看出来,asp.net 2.0的版本将是非常不错的一个产品。 官方网站:http://www.rainbowportal.net/Download - www.rainbowportal.net/site/3326/download.aspxFeatures - www.rainbowportal.net/site/3361/featu…...
被邀请做刷客会不会碰到钓鱼网站/百度快照怎么用
matplotlib.pyplot(as mp or as plt)提供基于python语言的绘图函数 引用方式: import matplotlib.pyplot as mp / as plt 本章内容拟按官方手册(NumPy Reference, Release 1.14.5 )中的 plt 形式 像matlab一样…...
如何在阿里云上做网站备案/2021年网络营销考试题及答案
摘要:本文首先对图像增强的原理进行一定的描述,其次给出了直方图增强、平滑处理、锐化处理、以及彩色增强几种常用的增强方法。并且分别对几种增强方法的原理和处理效果进行了对比研究。同时对这几种增强方法处理方式进行一定的讨论,然后根据在MATLAB中试…...
天津环保网站建设概念/百度引擎搜索推广
ANSI提供两种文件打开方式:二进制和文本。 fopen()和fclose(); 二进制读取写入用fread()和fwrite(); 从文件输入到缓存区的有fscanf()、getc()、fgets() 输出到文件的函数有 fprintf()、putc()、fputs(). 基本上一一对应。 将字符串写入数组s…...