OpenGL Chan视频学习-8 How I Deal with Shaders in OpenGL

news2025/7/21 2:42:04

bilibili视频链接:

【最好的OpenGL教程之一】https://www.bilibili.com/video/BV1MJ411u7Bc?p=5&vd_source=44b77bde056381262ee55e448b9b1973

函数网站:

docs.gl

说明:

1.之后就不再整理具体函数了,网站直接翻译会更直观也会有更多注意点。直接通过csdn索引查找反而会慢。

2.代码区域会单独注释功能参数返回值和相关注意事项。

3.课程学习从4-本节,如果有些函数没有注释可以看专栏里面的前面发表的文章,一般会有解释。 4.如果觉得代码注释白色字体不太直观可以直接copy到相应软件看。

5.有两种版本的可供查看:注释全面的和注释简洁版的,可以在索引里面找到相关代码查看。

6.希望能帮到你。

7.有错误请跟我说明一下,可能整理的时候没有检查好。

一、知识点整理

1.1 ShaderProgramSource结构体

//功能:定义ShaderProgramSource结构体,用于存储着色器代码
//方便ParseShader函数返回多个着色器代码
struct ShaderProgramSource
{
    std::string VertexSource;
    std::string FragmentSource;
};

1.2ParseShader函数

//功能:解析着色器代码文件。
//参数:filepath:着色器代码文件路径
//返回值:ShaderProgramSource结构体,包含着色器代码字符串
static ShaderProgramSource ParseShader(const std::string& filepath)
{
    //功能:打开文件流
    //参数:filepath:着色器代码文件路径
    std::ifstream stream(filepath);

    //定义着色器类型
    enum  class ShaderType
    {
        NONE=-1,VERTEX=0,FRAGMENT=1
    };

    //该变量用于存储着色器代码
    std::string line;
    //该变量用于存储着色器类型
    std::stringstream ss[2];
    //该变量是当前着色器类型
    ShaderType type = ShaderType::NONE;
    //功能:读取文件中的每一行内容,直到文件结束
    while (getline(stream, line))
    {
        //如果当前行包含#shader,则说明接下来是着色器代码
        //nposstd::string::npos 是 C++ 标准库中 std::string 类的一个静态成员。
        //它代表了一个无效的位置值,通常用于表示在字符串中未找到子字符串的情况。
        if (line.find("#shader") != std::string::npos)
        {
            //如果当前行包含vertex,则说明接下来是顶点着色器代码
            if (line.find("vertex") != std::string::npos)
            {
                type = ShaderType::VERTEX;
            }
            else if (line.find("fragment") != std::string::npos)
            {
                type = ShaderType::FRAGMENT;
            }
        }
        else
        {
            //否则,将当前行添加到对应着色器代码的stringstream中
            //ss[]是一个数组,用于存储着色器代码,通过ss[]<<line<<'\n'将当前行添加到对应着色器代码的stringstream中
            ss[(int)type] << line << '\n';
            std::cout << line << " hhh" << std::endl;
        }
    }
    //返回ShaderProgramSource结构体
    return { ss[0].str(), ss[1].str() };
}

1.3int main函数补充

//解析着色器代码文件
ShaderProgramSource source = ParseShader("res/shaders/Basic.shader");
std::string vertexShader = source.VertexSource;
std::string fragmentShader = source.FragmentSource;

std::cout << "VERTEX" << std::endl << vertexShader << std::endl;
std::cout << "FRAGMENT" << std::endl << fragmentShader << std::endl;

二、完整代码

1.1完全注释代码

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include<iostream>
#include<fstream>
#include<string>
#include<sstream>

//功能:定义ShaderProgramSource结构体,用于存储着色器代码
//方便ParseShader函数返回多个着色器代码
struct ShaderProgramSource
{
    std::string VertexSource;
    std::string FragmentSource;
};


//功能:解析着色器代码文件。
//参数:filepath:着色器代码文件路径
//返回值:ShaderProgramSource结构体,包含着色器代码字符串
static ShaderProgramSource ParseShader(const std::string& filepath)
{
    //功能:打开文件流
    //参数:filepath:着色器代码文件路径
    std::ifstream stream(filepath);

    //定义着色器类型
    enum  class ShaderType
    {
        NONE=-1,VERTEX=0,FRAGMENT=1
    };

    //该变量用于存储着色器代码
    std::string line;
    //该变量用于存储着色器类型
    std::stringstream ss[2];
    //该变量是当前着色器类型
    ShaderType type = ShaderType::NONE;
    //功能:读取文件中的每一行内容,直到文件结束
    while (getline(stream, line))
    {
        //如果当前行包含#shader,则说明接下来是着色器代码
        //nposstd::string::npos 是 C++ 标准库中 std::string 类的一个静态成员。
        //它代表了一个无效的位置值,通常用于表示在字符串中未找到子字符串的情况。
        if (line.find("#shader") != std::string::npos)
        {
            //如果当前行包含vertex,则说明接下来是顶点着色器代码
            if (line.find("vertex") != std::string::npos)
            {
                type = ShaderType::VERTEX;
            }
            else if (line.find("fragment") != std::string::npos)
            {
                type = ShaderType::FRAGMENT;
            }
        }
        else
        {
            //否则,将当前行添加到对应着色器代码的stringstream中
            //ss[]是一个数组,用于存储着色器代码,通过ss[]<<line<<'\n'将当前行添加到对应着色器代码的stringstream中
            ss[(int)type] << line << '\n';
        }
    }
    //返回ShaderProgramSource结构体
    return { ss[0].str(), ss[1].str() };
}


//功能:编译着色器代码
static unsigned int CompilesShader(unsigned int type, const std::string& source)
{
    //功能:创建着色器对象
    unsigned int id = glCreateShader(type);
    //功能:设置着色器源代码.
    const char* src = source.c_str();
    //功能:替换着色器对象中的源代码。将该id的指定着色器的源代码设置为src指针指向的字符串
    glShaderSource(id, 1, &src, nullptr);
    //功能:编译着色器对象的源代码
    glCompileShader(id);

    //设置返回着色器的对象ID
    int result;
    //功能:从着色器对象返回一个参数,表示编译是否成功。
    glGetShaderiv(id, GL_COMPILE_STATUS, &result);

    //如果编译失败,则输出错误信息
    if (result == GL_FALSE)
    {
        int length;
        //功能:获取编译错误信息的长度
        glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
        //分配内存,用于存储编译错误信息
        char* message = (char*)alloca(length*sizeof(char));
        //功能:获取编译错误信息
        glGetShaderInfoLog(id, length, &length, message);
        std::cout << "Failed to compile shader!" << (type == GL_VERTEX_SHADER? "Vertex" : "Fragment") << "shader!" << std::endl;
        std::cout << message << std::endl;
        //删除着色器对象
        glDeleteShader(id);
        return 0;
    }

    //TODO:错误处理ing
    return id;
}


//功能:创建着色器程序
static unsigned int CreateShader(const std::string& vertexShader, const std::string& fragmentShader)
{
    //创建程序对象
    unsigned int program = glCreateProgram();
    //编译顶点着色器对象
    unsigned int vs = CompilesShader(GL_VERTEX_SHADER, vertexShader);
    //编译片段着色器对象
    unsigned int fs = CompilesShader(GL_FRAGMENT_SHADER, fragmentShader);

    //功能:将编译好的着色器对象附加到程序对象中
    glAttachShader(program, vs);
    glAttachShader(program, fs);

    //功能:链接程序对象
    glLinkProgram(program);

    //功能:验证着色器程序对象是否可以在当前OpenGL状态中执行。检查着色器程序的完整性和可执行性。
    glValidateProgram(program);

    //删除着色器对象,因为它们已经被链接到程序对象中
    glDeleteShader(vs);
    glDeleteShader(fs);

    //返回着色器程序
    return program;
}


int main(void)
{
    GLFWwindow* window;

    //初始化glfw
    if (!glfwInit())
        return -1;

    //创建一个窗口模式的窗口并设置OpenGL上下文
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)//如果窗口创建失败,则终止程序
    {
        glfwTerminate();//释放glfw资源
        return -1;
    }

    //设置当前窗口的上下文,之后所有的OpenGL调用都会在这个上下文中进行
    glfwMakeContextCurrent(window);

    //初始化GLEW
    if (glewInit() != GLEW_OK)
        std::cout << "Error!" << std::endl;

    //打印OpenGL版本信息
    std::cout << glGetString(GL_VERSION) << std::endl;

    //准备数据
    float position[6] = {
        0.0f, 0.5f,
        -0.5f, -0.5f,
        0.5f, -0.5f
    };

    //定义缓冲区对象
    unsigned int buffer;
    //功能:生成缓冲区对象,并将数据写入缓冲区
    glGenBuffers(1, &buffer);
    //功能:将缓冲区对象绑定到目标
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    //功能:将数据写入缓冲区
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), position, GL_STATIC_DRAW);

    //功能:配置顶点属性指针
    glEnableVertexAttribArray(0);
    //功能:指定顶点属性数组的索引、大小、数据类型、是否归一化、偏移量、数据指针
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);

    //解析着色器代码文件
    ShaderProgramSource source = ParseShader("res/shaders/Basic.shader");
    std::string vertexShader = source.VertexSource;
    std::string fragmentShader = source.FragmentSource;

    std::cout << "VERTEX" << std::endl << vertexShader << std::endl;
    std::cout << "FRAGMENT" << std::endl << fragmentShader << std::endl;


    //创建着色器程序
    unsigned int shader = CreateShader(vertexShader, fragmentShader);
    //使用着色器程序
    glUseProgram(shader);

    //渲染循环,直到窗口被关闭
    while (!glfwWindowShouldClose(window))
    {
        //清除颜色缓冲区
        glClear(GL_COLOR_BUFFER_BIT);

        //功能:绘制三角形
        glDrawArrays(GL_TRIANGLES, 0, 3);

        //刷新缓冲区并交换窗口
        glfwSwapBuffers(window);

        //处理窗口事件,如键盘输入、鼠标移动等
        glfwPollEvents();
    }

    //删除着色器程序
    //glDeleteProgram(shader);

    //释放 GLFW 库占用的所有资源。
    glfwTerminate();
    return 0;
}

2.2简洁注释代码

#include <GL/glew.h>
#include <GLFW/glfw3.h>

#include<iostream>
#include<fstream>
#include<string>
#include<sstream>

//功能:定义ShaderProgramSource结构体,用于存储着色器代码
struct ShaderProgramSource
{
    std::string VertexSource;
    std::string FragmentSource;
};


//功能:解析着色器代码文件。
static ShaderProgramSource ParseShader(const std::string& filepath)
{
    //功能:打开文件流
    std::ifstream stream(filepath);

    //定义着色器类型
    enum  class ShaderType
    {
        NONE=-1,VERTEX=0,FRAGMENT=1
    };

    //该变量用于存储着色器代码
    std::string line;
    //该变量用于存储着色器类型
    std::stringstream ss[2];
    //该变量是当前着色器类型
    ShaderType type = ShaderType::NONE;
    //功能:读取文件中的每一行内容,直到文件结束
    while (getline(stream, line))
    {
        //如果当前行包含#shader,则说明接下来是着色器代码
        if (line.find("#shader") != std::string::npos)
        {
            //如果当前行包含vertex,则说明接下来是顶点着色器代码
            if (line.find("vertex") != std::string::npos)
            {
                type = ShaderType::VERTEX;
            }
            else if (line.find("fragment") != std::string::npos)
            {
                type = ShaderType::FRAGMENT;
            }
        }
        else
        {
            //否则,将当前行添加到对应着色器代码的stringstream中
            ss[(int)type] << line << '\n';
        }
    }
    //返回ShaderProgramSource结构体
    return { ss[0].str(), ss[1].str() };
}


//功能:编译着色器代码
static unsigned int CompilesShader(unsigned int type, const std::string& source)
{
    //功能:创建着色器对象
    unsigned int id = glCreateShader(type);
    //功能:设置着色器源代码.
    const char* src = source.c_str();
    //功能:替换着色器对象中的源代码。将该id的指定着色器的源代码设置为src指针指向的字符串
    glShaderSource(id, 1, &src, nullptr);
    //功能:编译着色器对象的源代码
    glCompileShader(id);

    //设置返回着色器的对象ID
    int result;
    //功能:从着色器对象返回一个参数,表示编译是否成功。
    glGetShaderiv(id, GL_COMPILE_STATUS, &result);

    //如果编译失败,则输出错误信息
    if (result == GL_FALSE)
    {
        int length;
        //功能:获取编译错误信息的长度
        glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
        //分配内存,用于存储编译错误信息
        char* message = (char*)alloca(length*sizeof(char));
        //功能:获取编译错误信息
        glGetShaderInfoLog(id, length, &length, message);
        std::cout << "Failed to compile shader!" << (type == GL_VERTEX_SHADER? "Vertex" : "Fragment") << "shader!" << std::endl;
        std::cout << message << std::endl;
        //删除着色器对象
        glDeleteShader(id);
        return 0;
    }

    //TODO:错误处理ing
    return id;
}


//功能:创建着色器程序
static unsigned int CreateShader(const std::string& vertexShader, const std::string& fragmentShader)
{
    //创建程序对象
    unsigned int program = glCreateProgram();
    //编译顶点着色器对象
    unsigned int vs = CompilesShader(GL_VERTEX_SHADER, vertexShader);
    //编译片段着色器对象
    unsigned int fs = CompilesShader(GL_FRAGMENT_SHADER, fragmentShader);

    //功能:将编译好的着色器对象附加到程序对象中
    glAttachShader(program, vs);
    glAttachShader(program, fs);

    //功能:链接程序对象
    glLinkProgram(program);

    //功能:验证着色器程序对象是否可以在当前OpenGL状态中执行。检查着色器程序的完整性和可执行性。
    glValidateProgram(program);

    //删除着色器对象,因为它们已经被链接到程序对象中
    glDeleteShader(vs);
    glDeleteShader(fs);

    //返回着色器程序
    return program;
}


int main(void)
{
    GLFWwindow* window;

    //初始化glfw
    if (!glfwInit())
        return -1;

    //创建一个窗口模式的窗口并设置OpenGL上下文
    window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);
    if (!window)//如果窗口创建失败,则终止程序
    {
        glfwTerminate();//释放glfw资源
        return -1;
    }

    //设置当前窗口的上下文,之后所有的OpenGL调用都会在这个上下文中进行
    glfwMakeContextCurrent(window);

    //初始化GLEW
    if (glewInit() != GLEW_OK)
        std::cout << "Error!" << std::endl;

    //打印OpenGL版本信息
    std::cout << glGetString(GL_VERSION) << std::endl;

    //准备数据
    float position[6] = {
        0.0f, 0.5f,
        -0.5f, -0.5f,
        0.5f, -0.5f
    };

    //定义缓冲区对象
    unsigned int buffer;
    //功能:生成缓冲区对象,并将数据写入缓冲区
    glGenBuffers(1, &buffer);
    //功能:将缓冲区对象绑定到目标
    glBindBuffer(GL_ARRAY_BUFFER, buffer);
    //功能:将数据写入缓冲区
    glBufferData(GL_ARRAY_BUFFER, 6 * sizeof(float), position, GL_STATIC_DRAW);

    //功能:配置顶点属性指针
    glEnableVertexAttribArray(0);
    //功能:指定顶点属性数组的索引、大小、数据类型、是否归一化、偏移量、数据指针
    glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(float) * 2, 0);

    //解析着色器代码文件
    ShaderProgramSource source = ParseShader("res/shaders/Basic.shader");
    std::string vertexShader = source.VertexSource;
    std::string fragmentShader = source.FragmentSource;

    std::cout << "VERTEX" << std::endl << vertexShader << std::endl;
    std::cout << "FRAGMENT" << std::endl << fragmentShader << std::endl;


    //创建着色器程序
    unsigned int shader = CreateShader(vertexShader, fragmentShader);
    //使用着色器程序
    glUseProgram(shader);

    //渲染循环,直到窗口被关闭
    while (!glfwWindowShouldClose(window))
    {
        //清除颜色缓冲区
        glClear(GL_COLOR_BUFFER_BIT);

        //功能:绘制三角形
        glDrawArrays(GL_TRIANGLES, 0, 3);

        //刷新缓冲区并交换窗口
        glfwSwapBuffers(window);

        //处理窗口事件,如键盘输入、鼠标移动等
        glfwPollEvents();
    }

    //删除着色器程序
    //glDeleteProgram(shader);

    //释放 GLFW 库占用的所有资源。
    glfwTerminate();
    return 0;
}

2.3运行结果

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

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

相关文章

机器学习课程设计报告 —— 基于口红数据集的情感分析

目录 一、课程设计目的 二、数据预处理及分析 2.1 数据预处理 2.2 数据分析 三、特征选择 3.1 特征选择的重要性 3.2 如何进行特征选择 3.3 特征选择的依据 3.4 数据集的划分 四、模型训练与模型评估 4.1 所有算法模型不调参 4.2 K-近邻分类模型 4.3 GaussianNB模…

Windows安装Docker部署dify,接入阿里云api-key进行rag测试

一、安装docker 1.1 傻瓜式安装docker Get Docker | Docker Docs Docker原理&#xff08;图解秒懂史上最全&#xff09;-CSDN博客 官网选择好windows的安装包下载&#xff0c;傻瓜式安装。如果出现下面的报错&#xff0c;说明主机没有安装WSL 1.2 解决办法 安装 WSL | Mic…

Dify中 SYSTEM, USER, ASSISTANT 的关系、职责与使用方法

在Dify这类对话式AI应用构建平台中,SYSTEM, USER, ASSISTANT 这三种消息类型共同定义了与大型语言模型(LLM)交互的结构和上下文。它们的关系可以理解为: SYSTEM: 扮演着“导演”或“场景设定者”的角色。USER: 扮演着“提问者”或“任务发起者”的角色。ASSISTANT: 扮演着“…

【ArcGIS Pro草履虫大师】空间地图系列

地图系列是根据单个布局来构建的页面集合。 正常情况下&#xff0c;一个布局只能导出一个页面&#xff0c;通过地图系列则可以通过不同的视图、动态元素&#xff0c;构建并导出多个页面。 地图系列发展自ArcMap的【数据驱动页面】功能。 ArcGIS Pro中有3个地图系列&#xff…

1. 数据结构基本概念 (1)

本文部分ppt、视频截图来自&#xff1a;[青岛大学-王卓老师的个人空间-王卓老师个人主页-哔哩哔哩视频] 1. 数据结构基本概念 1.1 研究内容 数据结构是一门研究非数值计算的程序设计中计算机操作队形以及他们之间关系和操作的核心课程&#xff0c;学习的主要内容如下&#x…

函数抓取图片microsoft excel与wps的区别

microsoft excel 写出index函数 找到图片所在的位置 INDEX(员工数据库!$H:$H,MATCH(Sheet1!$B$3,员工数据库!$A:$A,0))将index函数定义为名称 插入截图 插入-屏幕截图-屏幕剪辑 选中给截图插入定义的公式 WPS 直接写公式抓取

openpi π₀ 项目部署运行逻辑(三)——策略推理服务器 serve_policy.py

π₀ 主控脚本都在 scripts 中&#xff1a; 其中&#xff0c;serve_policy.py 是 openpi 中的策略推理服务端脚本&#xff0c;作用为&#xff1a;启动一个 WebSocket 服务器&#xff0c;加载预训练策略模型&#xff0c;等待外部请求&#xff08;如来自 main.py 的控制程序&…

基于vue框架的独居老人上门护理小程序的设计r322q(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。

系统程序文件列表 项目功能&#xff1a;用户,护理人员,服务预约,服务评价,服务类别,护理项目,请假记录 开题报告内容 基于Vue框架的独居老人上门护理小程序的设计开题报告 一、研究背景与意义 &#xff08;一&#xff09;研究背景 随着社会老龄化的加剧&#xff0c;独居老…

【前端】Hexo一键生成目录插件推荐_放入Hexo博客

效果 使用 安装 npm install hexo-auto-toc插件会自动对<article>包含下的所有内容进行解析&#xff0c;自动生成目录。如果你的文章页面结构中内容没被<article>包裹&#xff0c;需要自行添加它&#xff08;即blog文件夹下的index.html&#xff09;查看效果 hex…

宫格导航--纯血鸿蒙组件库AUI

摘要&#xff1a; 宫格导航(A_GirdNav)&#xff1a;可设置导航数据&#xff0c;建议导航项超过16个&#xff0c;可设置“更多”图标指向的页面路由。最多显示两行&#xff0c;手机每行最多显示4个图标&#xff0c;折叠屏每行最多6个图标&#xff0c;平板每行最多8个图标。多余图…

RNN 循环神经网络:原理与应用

一、RNN 的诞生背景 传统神经网络&#xff08;如 MLP、CNN&#xff09;在处理独立输入时表现出色&#xff0c;但现实世界中存在大量具有时序依赖的序列数据&#xff1a; 自然语言&#xff1a;"我喜欢吃苹果" 中&#xff0c;"苹果" 的语义依赖于前文 "…

若依框架 账户管理 用户分配界面解读

下载下来若依网站后 先对 后端代码进行解读 首先项目架构&#xff1a; 一般用 admin 这个比较多进行二次开发 其他 rouyi-common,rouyi-framework:为公共部分 rouyi-generator&#xff1a;代码生成部分 ruoyi-quartz&#xff1a;定时任务 ruoyi-system&#xff1a;系统任务 …

文档贡献 | 技术文档贡献流程及注意事项(保姆级教程)

内容目录 一、注册流程 二、创建分支&#xff08;Fork&#xff09; 三、使用GitLab界面更新文件的MR流程 四、使用Git命令行工具更新文件的MR流程 五、注意事项 一、注册流程 1、注册页面 在长安链平台注册页面&#xff0c;输入手机号码 &#xff0c;点击 “获取验证码”…

open-vscode-server +nodejs 安装

GitCode - 全球开发者的开源社区,开源代码托管平台GitCode是面向全球开发者的开源社区,包括原创博客,开源代码托管,代码协作,项目管理等。与开发者社区互动,提升您的研发效率和质量。https://gitcode.com/gh_mirrors/op/openvscode-server/?utm_sourceartical_gitcode&ind…

知行之桥如何将消息推送到钉钉群?

在钉钉平台中&#xff0c;机器人主要分为企业机器人和自定义机器人两类。本文将重点介绍如何通过自定义机器人&#xff0c;实现将知行之桥 EDI 系统的通知消息高效推送至钉钉群&#xff0c;帮助企业第一时间掌握业务动态。 一、在钉钉群中添加自定义机器人 在需要接收知行之桥…

09《从依赖管理到容器化部署:Maven 全链路实战笔记,解锁 Java 项目自动化构建的终极奥秘》

目录 一、Maven 核心基础强化 &#xff08;一&#xff09;Maven 架构与工作原理 1. 核心组件解析 2. 工作流程图示​编辑 &#xff08;二&#xff09;项目结构深度实践 1. 标准目录扩展说明 2. 多模块项目典型结构示例​编辑 二、依赖管理高级进阶 &#xff08;一&…

<el-date-picker>组件传参时,选中时间和传参偏差8小时

遇到一个bug&#xff0c;不仔细看&#xff0c;都不一定能发现&#xff0c;bug描述&#xff1a;我们有一个搜索框&#xff0c;里面有一个时间选择器&#xff0c;当我使用<el-date-picker>时&#xff0c;我发现当我选择时分秒之后&#xff0c;显示都正常&#xff0c;但是当…

ST MCU CAN模块--TTCAN模式浅析

ST MCU CAN模块使用总结 1 前言 ​ 传统CAN 采用事件触发消息传输机制,CSMA/ CD AMP( Carrier-Sense Mult iple Access w ith Co llision Detect ion and Arbit ration on Message Priorit ies, 载波侦听、多路访问、冲突检测、优先级仲裁) 介质访问控制机制, 即多个消息同时…

谷歌浏览器Google Chrome v137.0.7151.41 中文版本版+插件 v1.11.1

一、软件介绍 这个版本解压就可以用&#xff0c;界面是中文的。 保留了核心功能&#xff0c; 二、软件特点 便携性 &#xff1a;解压即可使用&#xff0c;不想用了直接删掉整个文件夹。 增强功能 &#xff1a;通过Chrome增强软件劫持补丁chromev1.11.1 x64 (version.dll)实现多…

国芯思辰| 同步降压转换器CN2020应用于智能电视,替换LMR33620

在智能电视不断向高画质、多功能、智能化发展的当下&#xff0c;其内部电源管理系统的性能至关重要。同步降压转换器可以为智能电视提供稳定、高效的运行。 国芯思辰CN2020是一款脉宽调制式同步降压转换器。内部集成两个功率MOS管&#xff0c;在4.5~18V宽输入电压范围内可以持…