OpenGL 冯氏光照模型

news2024/10/6 12:34:07

1.简介

现实世界的光照是极其复杂的,而且会受到诸多因素的影响,这是我们有限的计算能力所无法模拟的,冯氏光照模型的主要结构由3个分量组成:环境(Ambient)、漫反射(Diffuse)和镜面(Specular)光照。下面这张图展示了这些光照分量看起来的样子。

  • 环境光照(Ambient Lighting):即使在黑暗的情况下,世界上通常也仍然有一些光亮(月亮、远处的光),所以物体几乎永远不会是完全黑暗的。为了模拟这个,我们会使用一个环境光照常量,它永远会给物体一些颜色。
  • 漫反射光照(Diffuse Lighting):模拟光源对物体的方向性影响(Directional Impact)。它是冯氏光照模型中视觉上最显著的分量。物体的某一部分越是正对着光源,它就会越亮。
  • 镜面光照(Specular Lighting):模拟有光泽物体上面出现的亮点。镜面光照的颜色相比于物体的颜色会更倾向于光的颜色。

2.环境光照

我们使用一个很小的常量(光照)颜色,添加到物体片段的最终颜色中,这样子的话即便场景中没有直接的光源也能看起来存在有一些发散的光。

把环境光照添加到场景里非常简单。我们用光的颜色乘以一个很小的常量环境因子,再乘以物体的颜色,然后将最终结果作为片段的颜色:

void main()
{
    float ambientStrength = 0.1;
    vec3 ambient = ambientStrength * lightColor;

    vec3 result = ambient * objectColor;
    FragColor = vec4(result, 1.0);
}

3.漫反射光照

环境光照本身不能提供最有趣的结果,但是漫反射光照就能开始对物体产生显著的视觉影响了。漫反射光照使物体上与光线方向越接近的片段能从光源处获得更多的亮度。

上方有一个光源,它所发出的光线落在物体的一个片段上。我们需要测量这个光线是以什么角度接触到这个片段的。如果光线垂直于物体表面,这束光对物体的影响更亮。为了测量光线和片段的角度,我们使用一个叫做法向量的东西,它是垂直于片段表面的一个向量(这里以黄色箭头表示),这两个向量之间的角度很容易就能够通过点乘计算出来。 

所以,计算漫反射光照需要以下几点:

  • 法向量:一个垂直于顶点表面的向量。
  • 定向的光线:作为光源的位置与片段的位置之间向量差的方向向量。为了计算这个光线,我们需要光的位置向量和片段的位置向量。

以下是漫反射光照的计算。

光的方向向量lightDir是光源位置向量与片段位置向量之间的向量差。我们对norm和lightDir向量进行点乘,计算光源对当前片段实际的漫反射影响。结果值再乘以光的颜色,得到漫反射分量。两个向量之间的角度越大,漫反射分量就会越小;如果两个向量之间的角度大于90度,点乘的结果就会变成负数,这样会导致漫反射分量变为负数。为此,使用max函数返回两个参数之间较大的参数,从而保证漫反射分量不会变成负数。

    //diffuse
    vec3 norm = normalize(outNormal);    //法向量标准化
    vec3 lightDir = normalize(lightPos - FragPos);//光的方向向量是光源位置向量与片段位置向量之间的向量差
    float diff = max(dot(norm, lightDir), 0.0);//点乘
    vec3 diffuse = diff * lightColor;

片段着色器里的计算都是在世界空间坐标中进行的。所以,我们应该把法向量也转换为世界空间坐标 。如果模型矩阵执行了不等比缩放,顶点的改变会导致法向量不再垂直于表面了,这样光照就会被破坏。修复这个行为的诀窍是使用一个为法向量专门定制的模型矩阵。这个矩阵称之为法线矩阵

使用以下方法:

outNormal = mat3(transpose(inverse(model))) * normal;

4.镜面光照

和漫反射光照一样,镜面光照也决定于光的方向向量和物体的法向量,但是它也决定于观察方向,例如玩家是从什么方向看向这个片段的。镜面光照决定于表面的反射特性。如果我们把物体表面设想为一面镜子,那么镜面光照最强的地方就是我们看到表面上反射光的地方。你可以在下图中看到效果:

我们通过根据法向量翻折入射光的方向来计算反射向量(R)。然后我们计算反射向量与观察方向的角度差,它们之间夹角越小,镜面光的作用就越大。由此产生的效果就是,我们看向在入射光在表面的反射方向时,会看到一点高光。 

    //specular
    float specularStrength = 0.5;
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 reflectDir = reflect(-lightDir, norm);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
    vec3 specular = specularStrength * spec * lightColor;
  • 首先,我们定义一个镜面强度(Specular Intensity)变量,给镜面高光一个中等亮度颜色,让它不要产生过度的影响。
  • 计算视线方向向量(viewDir)和对应的沿着法线轴的反射向量(reflectDir)
  • 计算视线方向与反射方向的点乘(并确保它不是负值),然后取它的32次幂。这个32是高光的反光度(Shininess)

物体的反光度越高,反射光的能力越强,散射得越少,高光点就会越小。在下面的图片里,你会看到不同反光度的视觉效果影响:

剩下的最后一件事情是把它加到环境光分量和漫反射分量里,再用结果乘以物体的颜色:

vec3 result = (ambient + diffuse + specular) * objectColor;
FragColor = vec4(result, 1.0);

5.示例

#include "myopenglwidget.h"
#include <QMatrix4x4>
#include <QTime>
#include <QTimer>
#include <math.h>
#include <QDebug>

float vertices[] = {
    -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
};

GLuint indices[] = {
    0, 1, 3,
    1, 2, 3
};


GLuint VBO, VAO,EBO,lightVAO;
GLuint shaderProgram;

QVector3D lightPos(1.2f,1.0f,2.0f);
QVector3D lightColor(1.0f,1.0f,1.0f);
QVector3D objectColor(1.0f,0.5f,0.31f);

QTimer *timer;
QTime gtime;

QVector<QVector3D> cubePositions = {
  QVector3D( 0.0f,  0.0f,  0.0f),
  QVector3D( 2.0f,  5.0f, -15.0f),
  QVector3D(-1.5f, -2.2f, -2.5f),
  QVector3D(-3.8f, -2.0f, -12.3f),
  QVector3D( 2.4f, -0.4f, -3.5f),
  QVector3D(-1.7f,  3.0f, -7.5f),
  QVector3D( 1.3f, -2.0f, -2.5f),
  QVector3D( 1.5f,  2.0f, -2.5f),
  QVector3D( 1.5f,  0.2f, -1.5f),
  QVector3D(-1.3f,  1.0f, -1.5f)
};

float fov = 45.0f;

MyOpenGLWidget::MyOpenGLWidget(QWidget *parent)
    : QOpenGLWidget(parent)
{
    cameraPos = QVector3D( 0.0f,  0.0f,  5.0f);//摄像机位置
    cameraTarget = QVector3D( 0.0f,  0.0f,  0.0f);//摄像机看到的位置
    cameraDirection = QVector3D(cameraPos - cameraTarget);//摄像机的方向
    cameraDirection.normalize();

    up = QVector3D(0.0f,  1.0f,  0.0f);
    cameraRight = QVector3D::crossProduct(up,cameraDirection);//两个向量叉乘的结果会同时垂直于两向量,因此我们会得到指向x轴正方向的那个向量
    cameraRight.normalize();

    cameraUp = QVector3D::crossProduct(cameraDirection,cameraRight);
    cameraFront = QVector3D( 0.0f,  0.0f,  -1.0f);

    timer = new QTimer();
    timer->start(50);
    gtime.start();
    connect(timer,&QTimer::timeout,[=]{
        update();
    });

    setFocusPolicy(Qt::StrongFocus);
    //setMouseTracking(true);
}

void MyOpenGLWidget::initializeGL()
{
    initializeOpenGLFunctions();

    m_program = new QOpenGLShaderProgram();
    m_program->addShaderFromSourceFile(QOpenGLShader::Vertex,":/shapes.vert");
    m_program->addShaderFromSourceFile(QOpenGLShader::Fragment,":/shapes.frag");
    m_program->link();
    qDebug()<<m_program->log();

    m_lightProgram = new QOpenGLShaderProgram();
    m_lightProgram->addShaderFromSourceFile(QOpenGLShader::Vertex,":/light.vert");
    m_lightProgram->addShaderFromSourceFile(QOpenGLShader::Fragment,":/light.frag");
    m_lightProgram->link();


    glGenVertexArrays(1, &VAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(VAO);//绑定VAO
    glBindBuffer(GL_ARRAY_BUFFER, VBO);//顶点缓冲对象的缓冲类型是GL_ARRAY_BUFFER
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//把顶点数据复制到缓冲的内存中GL_STATIC_DRAW :数据不会或几乎不会改变。

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);

    glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)(3*sizeof(GLfloat)));
    glEnableVertexAttribArray(0);

    glGenBuffers(1, &EBO);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);


    glGenVertexArrays(1, &lightVAO);
    glGenBuffers(1, &VBO);

    glBindVertexArray(lightVAO);//绑定VAO
    glBindBuffer(GL_ARRAY_BUFFER, VBO);//顶点缓冲对象的缓冲类型是GL_ARRAY_BUFFER
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);//把顶点数据复制到缓冲的内存中GL_STATIC_DRAW :数据不会或几乎不会改变。

    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 6 * sizeof(GLfloat), (GLvoid*)0);
    glEnableVertexAttribArray(0);

    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindVertexArray(0);//解绑VAO

    m_program->bind();
    m_program->setUniformValue("objColor",objectColor);
    m_program->setUniformValue("lightColor",lightColor);
    m_program->setUniformValue("lightPos",lightPos);
    m_program->setUniformValue("viewPos",cameraPos);

    m_lightProgram->bind();
    m_lightProgram->setUniformValue("lightColor",lightColor);
}

void MyOpenGLWidget::paintGL()
{
    glClearColor(0.2f,0.3f,0.3f,1.0f);
    glEnable(GL_DEPTH_TEST);
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

    QMatrix4x4 model;
    QMatrix4x4 view;
    float time = gtime.elapsed()/50.0;
    //int time = QTime::currentTime().msec();

    QMatrix4x4 projection;
    projection.perspective(fov,(float)( width())/(height()),0.1,100);

    view.lookAt(cameraPos,cameraPos + cameraFront,up);

    m_program->bind();
    m_program->setUniformValue("projection",projection);
    m_program->setUniformValue("view",view);

    glBindVertexArray(VAO);//绑定VAO

    model.rotate(time,1.0f,5.0f,0.5f);
    m_program->setUniformValue("model",model);
    glDrawArrays(GL_TRIANGLES,0,36);

    m_lightProgram->bind();
    m_lightProgram->setUniformValue("projection",projection);
    m_lightProgram->setUniformValue("view",view);

    model.setToIdentity();
    model.translate(lightPos);
    model.rotate(1.0f,1.0f,5.0f,0.5f);
    model.scale(0.2);
    m_lightProgram->setUniformValue("model",model);
    glBindVertexArray(lightVAO);//绑定VAO
    glDrawArrays(GL_TRIANGLES,0,36);

//    foreach(auto pos , cubePositions)
//    {
//        model.setToIdentity();
//        model.translate(pos);
//        //model.rotate(time,1.0f,5.0f,3.0f);
//        m_program->setUniformValue("model",model);
//        glDrawArrays(GL_TRIANGLES,0,36);
//    }

}

void MyOpenGLWidget::resizeGL(int w, int h)
{

}

void MyOpenGLWidget::keyPressEvent(QKeyEvent *event)
{
    qDebug()<<event->key();
    cameraSpeed = 2.5 * 100 / 1000.0;
    switch (event->key()) {
    case Qt::Key_W:{
        cameraPos += cameraSpeed * cameraFront;
    }
        break;
    case Qt::Key_S:{
        cameraPos -= cameraSpeed * cameraFront;
    }
        break;
    case Qt::Key_A:{
        cameraPos -= cameraSpeed * cameraRight;
    }
        break;
    case Qt::Key_D:{
        cameraPos += cameraSpeed * cameraRight;
    }
        break;
    default:
        break;

    }
    update();
}
float PI = 3.1415926;
QPoint deltaPos;
void MyOpenGLWidget::mouseMoveEvent(QMouseEvent *event)
{
    static float yaw = -90;
    static float pitch = 0;
    static QPoint lastPos(width()/2,height()/2);
    auto currentPos = event->pos();
    deltaPos = currentPos-lastPos;
    lastPos=currentPos;
    float sensitivity = 0.1f;
    deltaPos *= sensitivity;
    yaw += deltaPos.x();
    pitch -= deltaPos.y();
    if(pitch > 89.0f) pitch = 89.0f;
    if(pitch < -89.0f) pitch = -89.0f;
    cameraFront.setX(cos(yaw*PI/180.0) * cos(pitch *PI/180));
    cameraFront.setY(sin(pitch*PI/180));
    cameraFront.setZ(sin(yaw*PI/180) * cos(pitch *PI/180));
    cameraFront.normalize();
    update();
}

void MyOpenGLWidget::wheelEvent(QWheelEvent *event)
{
    if(fov >= 1.0f && fov <= 75.0f)
        fov -= event->angleDelta().y()/120;
    if(fov <= 1.0f)
        fov = 1.0f;
    if(fov >= 75.0f)
        fov = 75.0f;

    update();
}

顶点着色器和片段着色器

#version 330 core

layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;
out vec3 outNormal;
out vec3 FragPos;

void main()
{
    outNormal = mat3(transpose(inverse(model))) * normal;
    FragPos = vec3(model * vec4(position,1.0));
    gl_Position = projection * view * model * vec4(position,1.0);
}




#version 330 core

out vec4 color;
uniform vec3 objColor;
uniform vec3 lightColor;
uniform vec3 lightPos;
uniform vec3 viewPos;

in vec3 outNormal;
in vec3 FragPos;

void main()
{
    //ambinet
    float ambinetStrength = 0.1;
    vec3 ambient = ambinetStrength * lightColor;

    //diffuse
    vec3 norm = normalize(outNormal);
    vec3 lightDir = normalize(lightPos - FragPos);
    float diff = max(dot(norm, lightDir), 0.0);
    vec3 diffuse = diff * lightColor;

    //specular
    float specularStrength = 0.5;
    vec3 viewDir = normalize(viewPos - FragPos);
    vec3 reflectDir = reflect(-lightDir, norm);
    float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);
    vec3 specular = specularStrength * spec * lightColor;

    vec3 result = (ambient + diffuse + specular) * objColor;

    color = vec4(result,1.0f);
}

6.完整源码

qt+opengl实现

https://download.csdn.net/download/wzz953200463/87893447icon-default.png?t=N4P3https://download.csdn.net/download/wzz953200463/87893447

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

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

相关文章

V4L2框架解析

和你一起终身学习&#xff0c;这里是程序员Android 经典好文推荐&#xff0c;通过阅读本文&#xff0c;您将收获以下知识点: 一、概览二、流程简介三、关键结构体四、模块初始化五、处理用户空间请求 一、概览 相机驱动层位于HAL Moudle与硬件层之间&#xff0c;借助linux内核驱…

MacOS使用docker安装nginx

文章目录 一、docker安装nginx1、查看可用的nginx2、安装Nginx镜像3、查看是否安装成功4、安装成功后执行nginx5、查看容器6、本地验证 二、创建本地挂载文件1、第一步&#xff1a;宿主机创建目录2、第二步&#xff1a;将docker安装的nginx里面文件复制到宿主机3、第三步&#…

安洵杯2023wp - ukfc战队

喜提牛马第23名&#xff0c;不过对于我来说尽力了。 主方向逆向、密码学都极限输出了、但是第二道同模的题差一个点没想通&#xff0c;没得写很难受。 补题&#xff1a;NULL Web CarelessPy 目录 Web CarelessPy Confronting robot Reverse ez_cpp babythread 3D_m…

深入学习 Mysql 引擎 InnoDB、MyISAM

tip&#xff1a;作为程序员一定学习编程之道&#xff0c;一定要对代码的编写有追求&#xff0c;不能实现就完事了。我们应该让自己写的代码更加优雅&#xff0c;即使这会费时费力。 &#x1f495;&#x1f495; 推荐&#xff1a;体系化学习Java&#xff08;Java面试专题&#…

【数据结构与算法】 01 链表 (单链表、双向链表、循环链表、块状链表、头结点、链表反转与排序、约瑟夫环问题)

一、线性表1.1 概念与特点1.2 线性表的存储结构1.3 常见操作1.4 应用场景 二、链表2.1 链表简介2.2 单向链表&#xff08;单链表&#xff09;2.21 基本概念2.22 单链表基本操作2.23 C语言实现▶ 带头结点▶ 不带头结点 2.3 双向链表2.31 基本概念2.32 与单链表比较2.33 双向链表…

【Python】Python进阶系列教程-- urllib(十三)

文章目录 前言urllib.requesturllib.errorurllib.parseurllib.robotparser 前言 往期回顾&#xff1a; Python进阶系列教程-- Python3 正则表达式&#xff08;一&#xff09;Python进阶系列教程-- Python3 CGI编程&#xff08;二&#xff09;Python进阶系列教程-- Python3 My…

C++面向对象丨3. 函数提高——默认参数、占位参数和函数重载

文章目录 系列文章目录基础入门面向对象 1 函数默认参数2 函数占位参数3 函数重载 系列文章目录 基础入门 C基础入门丨1. 初识C像极了C语言C基础入门丨2. 数据类型基础C基础入门丨3. 搞明白4类运算符——运算符C基础入门丨4. 程序结构有哪几种&#xff1f;——程序流程结构C基…

LVS负载均衡群集--NAT模式

目录 前言 一&#xff1a;企业群集应用概述 1、集群的含义 2、问题 3、 解决方法 二、企业群集分类 1、根据群集所针对的目标差异&#xff0c;可分为三种类型 2、负载均衡群集(Load Balance Cluster) 3、 高可用群集(High Availability Cluster) 4、 高性能运算群集(Hi…

华为OD机试真题 JavaScript 实现【素数伴侣】【2023 B卷 100分】,附详细解题思路

一、题目描述 若两个正整数的和为素数&#xff0c;则这两个正整数称之为“素数伴侣”&#xff0c;如2和5、6和13&#xff0c;它们能应用于通信加密。现在密码学会请你设计一个程序&#xff0c;从已有的 N &#xff08; N 为偶数&#xff09;个正整数中挑选出若干对组成“素数伴…

3 个令人惊艳的 AI 项目,开源了!

公众号关注 “GitHubDaily” 设为 “星标”&#xff0c;每天带你逛 GitHub&#xff01; 过去一周&#xff0c;从外界看&#xff0c;AI 貌似放缓了进步速度&#xff0c;但只有身处其中的人才能知道&#xff0c;AI 一直没有停下进化的脚步。 以下是 GitHub 过去一周&#xff0c;诞…

一杯奶茶,成为AIGC+CV视觉的前沿弄潮儿!

击上方“机器学习与AI生成创作”&#xff0c;关注星标 获取有趣、好玩的前沿干货&#xff01; 【AI生成创作与计算机视觉】知识星球 2022、2023年开始&#xff0c;基于扩散模型的AI绘画、ChatGPT系列大模型主导的AIGC狂潮已来&#xff01;大模型下的科研、工业应用方向&#xf…

YOLOV3——你总能在这找到你想要的答案

目录 一&#xff1a;前言&#xff1a; 二&#xff1a;更快&#xff0c;更强 网络结构图 其他基础操作&#xff1a; Darknet53的由来 三&#xff1a;最明显的特点&#xff1a; 四&#xff1a;多scale 五&#xff1a; 为什么vgg越深效果反而越差了&#xff1f; 六&#…

MySQL数据库(一)

前言 数据库分为关系型数据库和非关系型数据库&#xff0c;mysql属于关系型数据库。 SQL语法不区分大小写。 目录 前言 一、数据库的基础知识 &#xff08;一&#xff09;服务器和客户端的定义 &#xff08;二&#xff09;请求和响应 &#xff08;三&#xff09;MySQL的基…

uc-osⅡ入门——创建工程模板

目录 任务: 概念 简介 性质 组成 1) 核心部分(OSCore.c) 2) 任务处理部分(OSTask.c) 3) 时钟部分(OSTime.c) 4) 任务同步和通信部分 5) 与CPU的接口部分 总结分析和思考 任务管理 时间管理 内存管理 通信同步 任务调度 理解 实践 任务: 了解什么是ucos 创建…

Qt6构建于打包发布

打包发布 release 单文件打包 参考文献&#xff1a;https://blog.csdn.net/sasafa/article/details/126538432 首先准备我们欲打包发布的项目 默认情况下运行时发布的是 debug 类型的&#xff08;包含冗余调试信息&#xff0c;文件大&#xff09;&#xff0c;我们需要切换到 …

【利用AI让知识体系化】前端安全攻防知识点

文章目录 1. 前言1.1 前端安全攻防的意义1.2 概述前端安全攻防的范畴和流程 2. 攻击技术2.1 XSS攻击2.1.1 原理和类型2.1.2 预防和防御 2.2 CSRF攻击2.2.1 原理和类型2.2.2 预防和防御 3. 代码层次3.1 JavaScript代码安全3.1.1 客户端JavaScript安全3.1.2 服务器端JavaScript安…

从零玩转系列之微信支付安全

一、前言 halo各位大佬很久没更新了最近在搞微信支付,因商户号审核了我半个月和小程序认证也找了资料并且将商户号和小程序进行关联,至此微信支付Native支付完成.此篇文章过长我将分几个阶段的文章发布(项目源码都有,小程序和PC端) 在此之前已经更新了 微信支付开篇 二、微信支…

java SSM 宿舍管理系统myeclipse开发mysql数据库springMVC模式java编程计算机网页设计

一、源码特点 java SSM 宿舍管理系统是一套完善的web设计系统&#xff08;系统采用SSM框架进行设计开发&#xff0c;springspringMVCmybatis&#xff09;&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/…

docker部署gin项目

以如下这个简单的项目为例 创建Dockerfile文件 #指定构建镜像的基础镜像 FROM golang:1.18-alpine #开发者 MAINTAINER who # 为我们的镜像设置必要的环境变量 ENV GO111MODULEon \GOPROXYhttps://goproxy.cn,direct \CGO_ENABLED0 \GOOSlinux \GOARCHamd64#设置工作目录&…

集成运算放大器的线性应用(模电速成)

目录 1、运算电路基本认识 2、反向比例、同相比例运算电路 3、电压跟随器&#xff08;同相比例的特例&#xff09; 4、差分比例运算电路&#xff08;减法运算电路&#xff09; 5、积分、微分运算电路 1、运算电路基本认识 &#xff08;集成运放工作在线性区&#xff09; 两…