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

news2025/4/19 8:44:52

第一部分 概念:

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个面的纹理是挨个+1
    glTexImage2D(
    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;//纹理ID

    GLuint 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 以及绑定VAO
    glGenBuffers(1, &m_SkyBoxVboId);
    glBindBuffer(GL_ARRAY_BUFFER, m_SkyBoxVboId);
    glBufferData(GL_ARRAY_BUFFER, sizeof(skyboxVertices), skyboxVertices, GL_STATIC_DRAW);
    glGenVertexArrays(1, &m_SkyBoxVaoId);//创建VAO
    glBindVertexArray(m_SkyBoxVaoId);
    glBindBuffer(GL_ARRAY_BUFFER, m_SkyBoxVboId);//绑定VBO
    glEnableVertexAttribArray(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 以及绑定VAO
    glGenBuffers(1, &m_CubeVboId);
    glBindBuffer(GL_ARRAY_BUFFER, m_CubeVboId);
    glBufferData(GL_ARRAY_BUFFER, sizeof(cubeVertices), cubeVertices, GL_STATIC_DRAW);
    glGenVertexArrays(1, &m_CubeVaoId);//创建VAO
    glBindVertexArray(m_CubeVaoId);
    glBindBuffer(GL_ARRAY_BUFFER, m_CubeVboId);//绑定VBO
    glEnableVertexAttribArray(0);//属性O的数据
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (const void *) 0);
    glEnableVertexAttribArray(1);//属性1的数据 对应顶点着色器的location 1
    glVertexAttribPointer(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 texture
        glGenTextures(1, &m_TextureId);
        glBindTexture(GL_TEXTURE_CUBE_MAP, m_TextureId);//绑定立体纹理

        for (int i = 0; i < m_vcImage.size(); ++i)
        {
            //6个面的纹理是挨个+1
            glTexImage2D(
                    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 matrix
    glm::mat4 View = glm::lookAt(
            glm::vec3(0, 0, 1.8), // Camera is at (0,0,1), in World Space
            glm::vec3(0, 0, -1), // and looks at the origin
            glm::vec3(0, 1, 0)  // Head is up (set to 0,-1,0 to look upside-down)
    );

    // Model matrix
    glm::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;
}

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/619515.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CodeGeeX 2.0版本重大升级:通过聊天对话的方式直接操作代码

CodeGeeX 2.0版本正式上线&#xff01;从命名上看这是一次大版本的升级。 上个月&#xff0c;CodeGeeX在VSCode和JetBrains IDEs的插件中&#xff0c;加入了智能问答&#xff08;Ask CodeGeeX&#xff09;功能&#xff0c;让用户可以在IDE中通过问答对话的方式解决技术问题。本…

Selenium自动化程序被检测为爬虫,怎么屏蔽和绕过

Selenium 操作被屏蔽 使用selenium自动化网页时&#xff0c;有一定的概率会被目标网站识别&#xff0c;一旦被检测到&#xff0c;目标网站会拦截该客户端做出的网页操作。 比如淘宝和大众点评的登录页&#xff0c;当手工打开浏览器&#xff0c;输入用户名和密码时&#xff0c…

docker 无法将“docker”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。

&#x1f4a7; d o c k e r 无法将“ d o c k e r ”项识别为 . . . . . . \color{#FF1493}{docker 无法将“docker”项识别为......} docker无法将“docker”项识别为......&#x1f4a7; &#x1f337; 仰望天空&#xff0c;妳我亦是行人.✨ &#x1f984; 个人主页…

Elasticsearch:路由 - routing

你是否考虑过 Elasticsearch 如何知道将文档存储在何处&#xff1f; 它如何知道在哪里寻找它们&#xff0c;以及是否检索、更新或删除它们&#xff1f; 这是一个令人兴奋的过程&#xff0c;一切都归结为路由的概念。 路由介绍 路由是确定文档属于哪个分片以便检索它或将其存储在…

新手配learnsite

把下载好的learnsite放在C盘根目录下 改个名 开始&#xff0c;Microsoft SQL Server Tools 19,SQL Server Management studio 19 这里我其实是没看懂&#xff0c;但是我觉得是选个服务器。 点开数据库引擎这里试一下 因为我来回装好几次sql&#xff0c;这里只有ls2有印象好像是…

git statsh、git submodule

文章目录 git stash解决git pull和本地文件的冲突1、先将本地修改存储起来2、pull内容3、还原暂存的内容4、解决文件中冲突的的部分5、删除stash。6 、git stash pop 与 git stash apply <stash{id}> 的区别。 回退后的版本是不追踪的git 还原修改git submodule git stas…

SpringBoot整合达梦数据库的教程(详解)

一、官网下载试用版本 http://www.dameng.com/down.aspx 我是win 11系统下载如下&#xff1a; 二、安装 解压后 双击打开iso文件 然后点击安装 选择创建实例&#xff08;注意记住账号/密码 端口号 默认的是 SYSDBA/SYSDBA 5236&#xff09; 然后一直下一步 到完成&#xff…

Win11下查看快捷键占用情况

Win11下查看快捷键占用情况 使用 OpenArk&#xff0c;根据文档描述&#xff0c;它可以查看许多 Windows 系统信息&#xff0c;包括快捷键&#xff0c;支持 Win10。 操作步骤&#xff1a; 1.下载 OpenArk Github&#xff1a;https://github.com/BlackINT3/OpenArk 单文件下载&…

计算机毕业论文内容参考|基于c语言的新一代预约挂号系统的设计与实现

文章目录 导文文章重点前言系统架构相关技术与方法介绍网络通信技术数据库管理技术算法模型选择技术分析技术设计:技术实现:总结与展望:本文总结:后续工作展望:导文 计算机毕业论文内容参考|基于c语言的新一代预约挂号系统的设计与实现 文章重点 前言 随着科技的不断发展…

linuxOPS基础_linux软件包安装

软件包概述 上图是windows下的软件包 Linux下也有很多可以安装的软件&#xff0c;而这些软件的安装包可细分为两种&#xff0c;分别是源码包和二进制包。 Linux下软件的安装方式 ① RPM软件包安装 > 软件名称.rpm ② YUM包管理工具 > yum install 软件名称 -y ③ 源码…

红外-星光-黑光-全彩夜视摄像头选型

星光”、“黑光”、“AI超微光”、“极光”&#xff0c;在安防行业这些概念似乎比“低照度摄像机”本身要火的多。 无论营销名称是什么&#xff0c;归根到底&#xff0c;它们都是用不同的方法使摄像机能在夜间拍摄到更像白昼一般的 高清夜视摄像头除了以前我们在项目上经常使…

腾讯云服务器怎么使用?新手入门教程

腾讯云服务器入门教程包括云服务器CPU内存带宽配置选择&#xff0c;选择云服务器CVM或轻量应用服务器&#xff0c;云服务器创建后重置密码、远程连接、搭建程序环境等&#xff0c;腾讯云服务器网分享从0到1腾讯云服务器入门教程&#xff1a; 腾讯云服务器入门教程目录&#xf…

进程信号

目录 信号的产生方式 程序的崩溃 通过键盘产生 进程异常产生 系统调用产生 软件条件产生 信号产生中 函数介绍 sigset_t&#xff08;信号集&#xff09; sigprocmask函数 sigpending函数 信号处理 用户态和内核态的理解 处理信号的过程 信号捕捉 sigaction函数…

安全测试13款免费的测试工具!

目录 前言&#xff1a; 1. Excercise in a Box 2. Needle 3. DevSlop 4. 移动安全框架(Mobile Security Framework) 5. Frida 6. Nishang 7. Tamper 8. InSpec 9. Faraday 10. Pocsuite 11. Taipan 12. Pacu 13. Secure Guild 前言&#xff1a; 首先&#xff0c;我想强调一…

策略模式——实践:在业务逻辑中理解设计模式

一般定义 策略模式(Strategy Pattern)&#xff1a;定义一系列算法&#xff0c;将每一个算法封装起来&#xff0c;并让它们可以相互替换。策略模式让算法独立于使用它的客户而变化&#xff0c;也称为政策模式(Policy)。 主要角色 Context: 环境类 Strategy: 抽象策略类 Concr…

CnOpenData电商平台交易数据数据

一、数据简介 电子商务是网络化的新型经济活动&#xff0c;是推动“互联网&#xff0b;”发展的重要力量&#xff0c;是新经济的主要组成部分。通过电商平台获取的电商交易平台数据可以及时统计、监测数据&#xff0c;全方位跟踪分析电子商务市场的发展情况和发展环境&#xff…

mysql中的group by 和 having使用

mysql中的group by 和 having 使用 理论 –sql中的group by 用法解析&#xff1a; – Group By语句从英文的字面意义上理解就是“根据(by)一定的规则进行分组(Group)”。 –它的作用是通过一定的规则将一个数据集划分成若干个小的区域&#xff0c;然后针对若干个小区域进行数…

【Nginx+Tomcat的7层代理和四层代理】

目录 一、NginxTomcat负载均衡、动静分离1、正向代理2、反向代理3、Nginx动静分离实现原理Nginx静态处理优势 二、实战1.部署Nginx 负载均衡器2.部署2台Tomcat 应用服务器3.动静分离配置&#xff08;1&#xff09;Tomcat1 server 配置&#xff08;2&#xff09;Tomcat2 server …

【华为OD机试真题2023B卷 JAVAJS】评论转换输出

华为OD2023(B卷)机试题库全覆盖,刷题指南点这里 评论转换输出 时间限制:1s 空间限制:256MB 限定语言:不限 题目描述: 在一个博客网站上,每篇博客都有评论。每一条评论都是一个非空英文字母字符串。 评论具有树状结构,除了根评论外,每个评论都有一个父评论。 当评论保…

ciso模拟器配置RIP2

本文为ciso模拟器配置RIP2 操作笔记 (供新手参考&#xff09; 思科路由器设置ip地址怎么设置(思科模拟器中怎样给路由器配置ip地址) 方法一&#xff1a; 物理配置 https://www.luyouqi.com/shezhi/39347.html 方法二&#xff1a; 路由 CLI 配置 https://blog.csdn.net/qq_6…