十二、光照基础

news2025/2/25 3:38:55

第一部分概念

OpenGL ES的基础光照模型,目前opengl还无法模拟现实世界的复杂光照效果,但是为了效果上的逼真,还是引入了一些简单的模型来模拟光照效果,

这里介绍冯氏光照模型(Phong Lighting Model)模型,他是由三种元素光组成的,环境光,散射光,镜面光。

环境光:四面八方照射到物体上且各个方向都均匀的光,不依赖于光源位置,没有方向性。

要把环境光照添加到场景里,只需用光的颜色乘以一个(数值)很小常量环境因子,再乘以物体的颜色,然后使用它作为片段的颜色:
void main()
{
    float ambientStrength = 0.1f; //常量环境因子
    vec3 ambient = ambientStrength * lightColor; //环境光强度

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

散射光:散射光表示从物体表面向各个方向均匀反射的光。散射光的强度与入射光的强度及入射角密切相关,所以当光源位置发生变化,散射光效果也会发生明显变化。

out vec3 fragPos;//当前片段坐标
out vec3 normal; //当前片段法向量
uniform vec3 lightPos;//光源位置
void main()
{
    float diffuseStrength = 0.5f; //材质反射系数

	vec3 norm = normalize(normal); // 归一化
	vec3 lightDir = normalize(lightPos - fragPos);//当前片段光源照射方向向量

    float diff = max(dot(norm, lightDir), 0.0);// dot 表示两个向量的点乘
    vec3 diffuse = diffuseStrength * diff * lightColor; //散射光最终强度

    vec3 result = diffuse * objectColor;
    color = vec4(result, 1.0f);
}

镜面光:镜面光是由光滑物体表面反射的方向比较集中的光,镜面光强度不仅依赖于入射光与法向量的夹角,也依赖于观察者的位置。

out vec3 fragPos;//当前片段坐标
out vec3 normal; //当前片段法向量
uniform vec3 lightPos;//光源位置
void main()
{
    float specularStrength = 0.5f;

    vec3 norm = normalize(normal); // 归一化
    vec3 viewDir = normalize(viewPos - FragPos); //视线方向向量 
    vec3 reflectDir = reflect(-lightDir, norm); //镜面反射光向量

    float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32); 
    //视线方向向量与镜面反射光向量点乘的32次幂,这个32是高光的发光值(Shininess)。一个物体的发光值越高,反射光的能力越强,散射得越少,高光点越小。
    vec3 specular = specularStrength * spec * lightColor; //镜面光最终强度

    vec3 result = specular * objectColor;
    color = vec4(result, 1.0f);
}

第二部分实践

java部分与坐标系统是一致的,都有利用触摸来旋转的功能。主要是C++不一样。

这里新引入一种绘画方法:glDrawArrays

//提供绘制功能,从数组数据中提取数据渲染基本图元
//GL_TRIANGLES:把每三个顶点作为一个独立的三角形,顶点3n-2、3n-1和3n定义了第n个三角形,总共绘制N/3个三角形
glDrawArrays(GL_TRIANGLES, 0, 36);

提供了很多顶点坐标然后通过这种绘制,将3个顶点绘制成一个三角形,一个正方形两个三角形,一个立方体是六个正方形。因此绘制一个立方体需要36个顶点数据。

顶点着色器

#version 300 es
precision mediump float;//默认float 片段着色器需要指定
layout (location = 0) in vec4 a_position;
layout (location = 1) in vec2 a_texCoord;
layout(location = 2) in vec3 a_normal;
uniform mat4 u_MVPMatrix;//坐标变化矩阵
uniform mat4 u_ModelMatrix;//光照模型
uniform vec3 lightPos;//光照坐标
uniform vec3 lightColor;//光照颜色
uniform vec3 viewPos;//观察者坐标

out vec2 v_texCoord;//输出到片段着色器的纹理坐标
out vec3 ambient;//环境光

out vec3 diffuse;//散光
out vec3 specular;//反射

void main()
{
    gl_Position = u_MVPMatrix * a_position;
    vec3 fragPos = vec3(u_ModelMatrix * a_position);

    // Ambient环境光
    float ambientStrength = 0.1;
    ambient = ambientStrength * lightColor;

    // Diffuse散光
    float diffuseStrength = 0.5;
    vec3 unitNormal = normalize(vec3(u_ModelMatrix * vec4(a_normal, 1.0)));
    vec3 lightDir = normalize(lightPos - fragPos);
    float diff = max(dot(unitNormal, lightDir), 0.0);
    diffuse = diffuseStrength * diff * lightColor;

    // Specular镜面
    float specularStrength = 0.9;
    vec3 viewDir = normalize(viewPos - fragPos);
    vec3 reflectDir = reflect(-lightDir, unitNormal);
    float spec = pow(max(dot(unitNormal, reflectDir), 0.0), 16.0);
    specular = specularStrength * spec * lightColor;

    v_texCoord = a_texCoord;
}

片段着色器

#version 300 es
precision mediump float;
layout(location = 0) out vec4 outColor;

in vec2 v_texCoord;
in vec3 ambient;
in vec3 diffuse;
in vec3 specular;

uniform sampler2D s_TextureMap;
void main()
{
    vec4 objectColor = texture(s_TextureMap, v_texCoord);
    vec3 finalColor = (ambient + diffuse + specular) * vec3(objectColor);
    outColor = vec4(finalColor, 1.0);;
}

Basiclighting.h

//
// Created by CreatWall_zhouwen on 2023/5/10.
//

#ifndef SEVENBASICLIGHTING_BASICLIGHTING_H
#define SEVENBASICLIGHTING_BASICLIGHTING_H

#include <GLES3/gl3.h>
#include <detail/type_mat.hpp>
#include <detail/type_mat4x4.hpp>
#define MATH_PI 3.1415926535897932384626433832802

class Basiclighting {
public:
    Basiclighting(){
        program = 0;
        vertexShaderHandle = 0;
        fragShaderHandle = 0;
        m_ModelMatrix = glm::mat4(0.0f);
        m_AngleX = 0;
        m_AngleY = 0;
        m_ScaleX = 1.0f;
        m_ScaleY = 1.0f;
        m_ModelMatrix = glm::mat4(0.0f);
    };
    ~Basiclighting(){};
    void CreateProgram(const char *ver, const char *frag);
    void Draw();
    void getTexturedata(unsigned char *data, int width, int height);
    static Basiclighting* 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 ratio);
private:
    GLuint program;
    GLuint vertexShaderHandle;
    GLuint fragShaderHandle;
    GLuint m_VaoId;//存放顶点数据
    GLuint m_VboId;//顶点缓冲区
    unsigned int m_TextureId;
    unsigned char *texturedata;
    int texturewidth, textureheight;

    int srceenWidth, srceenHeight;//屏幕宽高
    GLint m_SamplerLoc;
    GLint m_MVPMatLoc;
    GLint m_ModelMatrixLoc;
    GLint m_LightPosLoc;
    GLint m_LightColorLoc;
    GLint m_ViewPosLoc;

    glm::mat4 m_MVPMatrix;
    glm::mat4 m_ModelMatrix;
    int m_AngleX;
    int m_AngleY;
    float m_ScaleX;
    float m_ScaleY;
};



#endif //SEVENBASICLIGHTING_BASICLIGHTING_H

Basiclighting.cpp

//
// Created by CreatWall_zhouwen on 2023/5/10.
//

#include "Basiclighting.h"
#include "Util.h"
#include "GLUtil.h"
#include <gtc/matrix_transform.hpp>
Basiclighting* m_pContext = nullptr;
#define TAG "DRAWTEXTURE"

GLfloat vertices[] = {
        //position            //texture coord  //normal
        -0.5f, -0.5f, -0.5f,   0.0f, 0.0f,      0.0f,  0.0f, -1.0f,
        0.5f, -0.5f, -0.5f,   1.0f, 0.0f,      0.0f,  0.0f, -1.0f,
        0.5f,  0.5f, -0.5f,   1.0f, 1.0f,      0.0f,  0.0f, -1.0f,
        0.5f,  0.5f, -0.5f,   1.0f, 1.0f,      0.0f,  0.0f, -1.0f,
        -0.5f,  0.5f, -0.5f,   0.0f, 1.0f,      0.0f,  0.0f, -1.0f,
        -0.5f, -0.5f, -0.5f,   0.0f, 0.0f,      0.0f,  0.0f, -1.0f,

        -0.5f, -0.5f, 0.5f,    0.0f, 0.0f,      0.0f,  0.0f,  1.0f,
        0.5f, -0.5f, 0.5f,    1.0f, 0.0f,      0.0f,  0.0f,  1.0f,
        0.5f,  0.5f, 0.5f,    1.0f, 1.0f,      0.0f,  0.0f,  1.0f,
        0.5f,  0.5f, 0.5f,    1.0f, 1.0f,      0.0f,  0.0f,  1.0f,
        -0.5f,  0.5f, 0.5f,    0.0f, 1.0f,      0.0f,  0.0f,  1.0f,
        -0.5f, -0.5f, 0.5f,    0.0f, 0.0f,      0.0f,  0.0f,  1.0f,

        -0.5f,  0.5f,  0.5f,   1.0f, 0.0f,     -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f, -0.5f,   1.0f, 1.0f,     -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, -0.5f,   0.0f, 1.0f,     -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f, -0.5f,   0.0f, 1.0f,     -1.0f,  0.0f,  0.0f,
        -0.5f, -0.5f,  0.5f,   0.0f, 0.0f,     -1.0f,  0.0f,  0.0f,
        -0.5f,  0.5f,  0.5f,   1.0f, 0.0f,     -1.0f,  0.0f,  0.0f,

        0.5f,  0.5f,  0.5f,   1.0f, 0.0f,      1.0f,  0.0f,  0.0f,
        0.5f,  0.5f, -0.5f,   1.0f, 1.0f,      1.0f,  0.0f,  0.0f,
        0.5f, -0.5f, -0.5f,   0.0f, 1.0f,      1.0f,  0.0f,  0.0f,
        0.5f, -0.5f, -0.5f,   0.0f, 1.0f,      1.0f,  0.0f,  0.0f,
        0.5f, -0.5f,  0.5f,   0.0f, 0.0f,      1.0f,  0.0f,  0.0f,
        0.5f,  0.5f,  0.5f,   1.0f, 0.0f,      1.0f,  0.0f,  0.0f,

        -0.5f, -0.5f, -0.5f,   0.0f, 1.0f,      0.0f, -1.0f,  0.0f,
        0.5f, -0.5f, -0.5f,   1.0f, 1.0f,      0.0f, -1.0f,  0.0f,
        0.5f, -0.5f,  0.5f,   1.0f, 0.0f,      0.0f, -1.0f,  0.0f,
        0.5f, -0.5f,  0.5f,   1.0f, 0.0f,      0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f,  0.5f,   0.0f, 0.0f,      0.0f, -1.0f,  0.0f,
        -0.5f, -0.5f, -0.5f,   0.0f, 1.0f,      0.0f, -1.0f,  0.0f,

        -0.5f, 0.5f, -0.5f,    0.0f, 1.0f,      0.0f,  1.0f,  0.0f,
        0.5f, 0.5f, -0.5f,    1.0f, 1.0f,      0.0f,  1.0f,  0.0f,
        0.5f, 0.5f,  0.5f,    1.0f, 0.0f,      0.0f,  1.0f,  0.0f,
        0.5f, 0.5f,  0.5f,    1.0f, 0.0f,      0.0f,  1.0f,  0.0f,
        -0.5f, 0.5f,  0.5f,    0.0f, 0.0f,      0.0f,  1.0f,  0.0f,
        -0.5f, 0.5f, -0.5f,    0.0f, 1.0f,      0.0f,  1.0f,  0.0f,
};

void Basiclighting::CreateProgram(const char *ver, const char *frag) {
    LOGD("CreateProgram Enter");
    // 编译链接用于离屏渲染的着色器程序
    program = CreateGLProgram(ver, frag, vertexShaderHandle, fragShaderHandle);
    if (program == GL_NONE)
    {
        LOGD("FBOSample::Init m_ProgramObj == GL_NONE");
        return;
    }
    LOGD("CreateGLProgram Success");
    m_SamplerLoc = glGetUniformLocation(program, "s_TextureMap");
    m_MVPMatLoc = glGetUniformLocation(program, "u_MVPMatrix");
    m_ModelMatrixLoc = glGetUniformLocation(program, "u_ModelMatrix");
    m_LightPosLoc = glGetUniformLocation(program, "lightPos");
    m_LightColorLoc = glGetUniformLocation(program, "lightColor");
    m_ViewPosLoc = glGetUniformLocation(program, "viewPos");

    //创建VBO
    glGenBuffers(1, &m_VboId);
    glBindBuffer(GL_ARRAY_BUFFER, m_VboId);
    glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);

    //创建VAO绑定VAO和纹理
    glGenVertexArrays(1, &m_VaoId);
    glBindVertexArray(m_VaoId);
    glBindBuffer(GL_ARRAY_BUFFER, m_VboId);
    glEnableVertexAttribArray(0);
    glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (const void *) 0);
    glEnableVertexAttribArray(1);
    glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (const void *) (3* sizeof(GLfloat)));
    glEnableVertexAttribArray(2);
    glVertexAttribPointer(2, 3, GL_FLOAT, GL_FALSE, 8 * sizeof(GLfloat), (const void *) (5* sizeof(GLfloat)));
    glBindBuffer(GL_ARRAY_BUFFER, GL_NONE);

    glGenTextures(1, &m_TextureId);
    glBindTexture(GL_TEXTURE_2D, m_TextureId);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    //绑定纹理数据
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texturewidth, textureheight, 0, GL_RGB, GL_UNSIGNED_BYTE, texturedata);
    glGenerateMipmap(GL_TEXTURE_2D);
    glBindTexture(GL_TEXTURE_2D, GL_NONE);
}

void Basiclighting::Draw() {
    glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
    glClearColor(0.2f, 0.9f, 0.3f, 1.0f);
    UpdateMVPMatrix(m_MVPMatrix, m_AngleX, m_AngleY, (float) srceenWidth / srceenHeight);
    glEnable(GL_DEPTH_TEST);//启用深度测试,注意glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);也要进行清除
    glUseProgram(program);
    glBindVertexArray(m_VaoId);

    //设置参数
    glUniformMatrix4fv(m_MVPMatLoc, 1, GL_FALSE, &m_MVPMatrix[0][0]);
    glUniformMatrix4fv(m_ModelMatrixLoc, 1, GL_FALSE, &m_ModelMatrix[0][0]);
    glUniform3f(m_LightColorLoc,  1.0f, 1.0f, 1.0f);
    glUniform3f(m_LightPosLoc,    -2.0f, 0.0f, 2.0f);
    glUniform3f(m_ViewPosLoc,     -3.0f, 0.0f, 3.0f);

    //绑定纹理
    glBindTexture(GL_TEXTURE_2D, m_TextureId);
    glUniform1i(m_SamplerLoc, 0);

    //提供绘制功能,从数组数据中提取数据渲染基本图元
    //GL_TRIANGLES:把每三个顶点作为一个独立的三角形,顶点3n-2、3n-1和3n定义了第n个三角形,总共绘制N/3个三角形
    glDrawArrays(GL_TRIANGLES, 0, 36);

    glBindVertexArray(0);
}



Basiclighting *Basiclighting::GetInstance() {
    if (m_pContext == nullptr)
    {
        m_pContext = new Basiclighting();
    }
    return m_pContext;
}

void Basiclighting::DestroyInstance() {
    if (m_pContext)
    {
        delete m_pContext;
        m_pContext = nullptr;
    }
}

void Basiclighting::getTexturedata(unsigned char *data, int width, int height) {
    texturedata = data;
    texturewidth = width;
    textureheight = height;
}

void Basiclighting::OnSurfaceChanged(int width, int height) {
    glViewport(0, 0, width, height);
    srceenWidth = width;
    srceenHeight = height;
}

void Basiclighting::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 Basiclighting::UpdateMVPMatrix(glm::mat4 &mvpMatrix, int angleX, int angleY, float ratio) {
    LOGD("BasicLightingSample::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(-3, 0, 3), // Camera is at (0,0,1), in World Space
            glm::vec3(0, 0, 0), // 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(m_ScaleX, m_ScaleX, m_ScaleX));
    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;
}

在这里插入图片描述

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

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

相关文章

大数据:spark RDD编程,构建,RDD算子,map,flatmap,reduceByKey,mapValues,groupBy,

大数据&#xff1a;spark RDD编程 2022找工作是学历、能力和运气的超强结合体&#xff0c;遇到寒冬&#xff0c;大厂不招人&#xff0c;可能很多算法学生都得去找开发&#xff0c;测开 测开的话&#xff0c;你就得学数据库&#xff0c;sql&#xff0c;oracle&#xff0c;尤其s…

618有什么数码好物值得购买?2023值得入手的数码好物推荐

在618期间&#xff0c;有哪些值得入手的数码好物&#xff1f;很多人还不知道有哪些数码好物值得买的&#xff0c;本文推荐几款质量不错数码好物&#xff0c;助您尽情享受618购物买买买。 一、南卡OE不入耳蓝牙耳机 推荐理由&#xff1a; 南卡OE耳机是一款性价比超高的不入耳蓝…

进公司第一天当老板问:“测得怎么样了?”我懵逼了

当我入行做测试头两份年&#xff0c;觉的测试工作有时候似乎挺苦逼的&#xff0c;我太难了…… 前言 说实话&#xff0c;我真想从上面去掉"似乎"两个字&#xff0c;软件测试人&#xff0c;就是苦逼&#xff01;有的人曾抱怨过开发很糟糕&#xff0c;但我们没办法要求…

用AI生成思维导图的方法

写在前边&#xff1a; 这篇文章很简单&#xff0c;只为给自己做个记录。并且做一个简单的思考&#xff1a;明明很容易的东西&#xff0c;一旦陷入了思维困境中&#xff0c;就无法找到出去的路。这时候需要扩展思维或者他人提点。 正文&#xff1a; 就挺尴尬&#xff0c;之前…

计算机毕业论文内容参考|基于python的农业温室智能管理系统的设计与实现

文章目录 导文文章重点前言课题内容相关技术与方法介绍技术分析技术设计技术设计技术实现方面系统测试和优化总结与展望本文总结后续工作展望导文 计算机毕业论文内容参考|基于python的农业温室智能管理系统的设计与实现 文章重点 前言 本文介绍了一种基于Python的农业温室智…

玩过Tauri和Electron,最终我选择Flutter进行跨平台应用开发

Flutter、Tauri 和 Electron 都是现代桌面应用程序开发的流行选择&#xff0c;每种技术有其独特的优缺点&#xff0c;下面我们就来对它们进行一个全面的技术对比。 一、Flutter Flutter 是 Google 推出的一款开源的 UI 工具包&#xff0c;用于构建高性能、高保真度的移动、We…

2023年6月杭州/广州/深圳NPDP产品经理认证找这里

产品经理国际资格认证NPDP是新产品开发方面的认证&#xff0c;集理论、方法与实践为一体的全方位的知识体系&#xff0c;为公司组织层级进行规划、决策、执行提供良好的方法体系支撑。 【认证机构】 产品开发与管理协会&#xff08;PDMA&#xff09;成立于1979年&#xff0c;是…

从搜索电商,社交电商到兴趣电商如何进化

【搜索电商】需求>联结>信任 淘宝、天猫、京东这些是属于什么电商&#xff1f; 答&#xff1a;这些都是属于搜索电商。 某宝&#xff0c;某东等用户有需求&#xff0c;才能产生主动寻找商品的触点&#xff0c;由第三方担保&#xff0c;产生信任。 试想一下&#xff0c;我…

高逼格的 SQL 写法:行行比较

码农code之路 2023-06-01 08:28 发表于天津 环境准备 需求背景 循环查询 OR 拼接 混查过滤 行行比较 总结 环境准备 数据库版本&#xff1a;MySQL 5.7.20-log 建表 SQL DROP TABLE IF EXISTS t_ware_sale_statistics; CREATE TABLE t_ware_sale_statistics (id bigin…

面向过程 VS 面向对象

学习编程&#xff0c; 基本功是掌握编程语言&#xff0c;但编程的本质是逻辑&#xff0c;所以编程思维的培养也很重要。面向过程和面向对象是两种重要的编程思想&#xff0c;下面讲述一下这两者的区别和优缺点比较。 1. 面向过程 面向过程是一种以事件为中心的编程思想&#…

cmake编译报错

CMake Error &#xff1a;The source.. 此处大概意思是一个文件地址does not match the 另外一个文件地址so used to generate cache. Rerun cmake...解决方法&#xff1a; vscode 快捷键ctrl shift P &#xff0c;点击第一行的删除cmake 缓存 或者将 build 下的 CMakeCac…

算法百花齐放:探索常见算法的精妙之道

在计算机科学的领域中&#xff0c;算法是一项关键而令人着迷的技术。它们是解决问题、优化效率以及创造智能系统的核心。从简单的排序和搜索任务到复杂的机器学习和深度学习应用&#xff0c;常见算法为我们提供了解决各种挑战的有力工具。在本篇博客中&#xff0c;我们将探索常…

chatgpt赋能python:Python如何过滤某个字母——关于SEO的建议

Python如何过滤某个字母——关于SEO的建议 SEO&#xff08;搜索引擎优化&#xff09;是现代网络营销中的一个重要概念。为了让自己的网站在搜索引擎排名中更加靠前&#xff0c;许多管理员和开发人员都在使用Python等编程语言来过滤特定的字母或符号&#xff0c;以优化关键词的…

linux服务器更新yum源,安装 dnf包管理器

进入yum目录 cd /etc/yum.repos.dls 查看 备份 将“CentOS-Base.repo”重命名备份为“CentOS-Base.repo.backup” mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentOS-Base.repo.backup下载yum源并查看 下载对应版本 repo 文件, 放入 /etc/yum.repos.d/ (操作前请…

MAC 安装配置Tomcat

一、安装Tomcat 1、首先到官网下载Tomcat&#xff1a;https://tomcat.apache.org/download-80.cgi 2、解压tomcat文件,可以通过快捷键(commandshiftG)把它放入/Library(资源库中) 二、用终端打开Tomcat 1.在Bin目录下 打开终端 2.授权bin目录下的所有操作&#xff1a;终端…

Gradle Kotlin 规范插件用于模块化结构 - 共享构建逻辑

Gradle Kotlin 规范插件用于模块化结构 - 共享构建逻辑 我们中的许多人都遇到过Groovy的困难&#xff0c;并习惯于将其转换为Kotlin DSL。 然后&#xff0c;作为Android工程师&#xff0c;在完全使用Kotlin编写的项目上工作是纯粹的喜悦。 我们假设采用基于功能的模块化应用程…

PLSQL Developer 14安装

资源 百度网盘&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1A4DeaKPF7y-0o90nVKFbZA?pwd6udw 提取码&#xff1a;6udw阿里网盘&#xff1a; PLSQL Developer 14破解版 https://www.aliyundrive.com/s/zUdgF98VCE3安装步骤 解压安装包后&#xff0c;获得PLSQL De…

chatgpt赋能python:Python如何访问网页

Python如何访问网页 Python是一种被广泛用于web开发、数据科学和人工智能的编程语言。但是&#xff0c;你知道Python还可以用于访问网页吗&#xff1f;在本文中&#xff0c;我们将介绍Python如何访问网页&#xff0c;帮助您了解Python的这一方面&#xff0c;并掌握它的实际应用…

什么是快捷支付?

快捷支付是一种便捷的支付方式&#xff0c;它允许用户使用预先绑定的银行卡或支付账户进行快速支付&#xff0c;无需重复输入卡号、密码等详细信息。 编辑搜图 请点击输入图片描述&#xff08;最多18字&#xff09; 在快捷支付中&#xff0c;用户可以在商家网站、移动应用或支…

详解YOLOv6.2 Repvgg-style 的高效backbone:EfficientRep

论文地址: https://arxiv.org/pdf/2302.00386v1.pdf github: https://github.com/meituan/YOLOv6/releases I. 引言 自从VGG在图像分类任务中取得成功以来,卷积神经网络设计已经引起了学术界和工业界的广泛关注。目前已经提出了大量经典网络,如Inception和Resnet等。这些精心…