当前位置: 首页 > news >正文

使用Assimp加载glb/gltf文件,然后使用Qt3D来渲染

文章目录

  • 1.代码
  • 2.说明
    • 2.1.调用
    • 2.2.关于贴图

1.代码

ModelLoader.h

#ifndef MODELLOADER_H
#define MODELLOADER_H#include <QObject>
#include <Qt3DRender>
#include <QVector3D>
#include <QGeometry>#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>struct Triangle
{int vertexIndex1 { 0 };int vertexIndex2 { 0 };int vertexIndex3 { 0 };bool operator==(const Triangle &rhs) const {return vertexIndex1 == rhs.vertexIndex1 &&vertexIndex2 == rhs.vertexIndex2 &&vertexIndex3 == rhs.vertexIndex3;}
};namespace RenderAttributes
{
Qt3DRender::QAttribute *create(const QVector<Triangle> &triangles, Qt3DRender::QGeometry *parent);
Qt3DRender::QAttribute *create(const QVector<QVector3D> &vertices, const QString &name, Qt3DRender::QGeometry *parent);
Qt3DRender::QAttribute *clone(Qt3DRender::QAttribute *from, Qt3DRender::QGeometry *parent);
}class ModelLoader
{
public:ModelLoader();// 加载模型static int loadModelFromFile(Qt3DCore::QEntity *rootEntity, QString filePath);private:static int processNode(aiNode *node, const aiScene *scene, Qt3DCore::QEntity *entity);static int processMesh(aiMesh *mesh, const aiScene *scene, Qt3DCore::QEntity *entity);
};class MyQPaintedTextureImage : public Qt3DRender::QPaintedTextureImage
{
public:void setImage(QImage &i){image = i;setSize(i.size());}virtual void paint(QPainter *painter) override{painter->drawImage(0, 0, image);}private:QImage image;
};
#endif // MODELLOADER_H

ModelLoader.cpp

#include "modelloader.h"
#include <Qt3DExtras>
#include <Qt3DRender>
#include <QPaintedTextureImage>Qt3DRender::QAttribute *RenderAttributes::create(const QVector<Triangle> &triangles, Qt3DRender::QGeometry *parent)
{auto attribute = new Qt3DRender::QAttribute(parent);QVector<uint> indices;indices.reserve(triangles.size() * 3);for (const Triangle &triangle : triangles) {indices << static_cast<uint>(triangle.vertexIndex1)<< static_cast<uint>(triangle.vertexIndex2)<< static_cast<uint>(triangle.vertexIndex3);}Qt3DRender::QBuffer *dataBuffer = new Qt3DRender::QBuffer(attribute);const int rawSize = indices.size() * static_cast<int>(sizeof(uint));auto rawData = QByteArray::fromRawData(reinterpret_cast<const char*>(indices.constData()), rawSize);rawData.detach();dataBuffer->setData(rawData);attribute->setAttributeType(Qt3DRender::QAttribute::IndexAttribute);attribute->setBuffer(dataBuffer);attribute->setVertexBaseType(Qt3DRender::QAttribute::UnsignedInt);attribute->setVertexSize(1);attribute->setByteOffset(0);attribute->setByteStride(sizeof(uint));attribute->setCount(static_cast<uint>(indices.size()));return attribute;
}
Qt3DRender::QAttribute *RenderAttributes::create(const QVector<QVector3D> &vertices, const QString &name, Qt3DRender::QGeometry *parent)
{auto attribute = new Qt3DRender::QAttribute(parent);QVector<float> values;values.reserve(vertices.size() * 3);for (const QVector3D &v : vertices) {values << v.x() << v.y() << v.z();}Qt3DRender::QBuffer *dataBuffer = new Qt3DRender::QBuffer(attribute);const int rawSize = values.size() * static_cast<int>(sizeof(float));auto rawData = QByteArray::fromRawData(reinterpret_cast<const char*>(values.constData()), rawSize);rawData.detach();dataBuffer->setData(rawData);attribute->setAttributeType(Qt3DRender::QAttribute::VertexAttribute);attribute->setBuffer(dataBuffer);attribute->setVertexBaseType(Qt3DRender::QAttribute::Float);attribute->setVertexSize(3);attribute->setByteOffset(0);attribute->setByteStride(3 * sizeof(float));attribute->setName(name);attribute->setCount(static_cast<uint>(vertices.size()));return attribute;
}uint qHash(const QVector3D &key, uint seed = 0)
{if (key.isNull()){return seed;}else{float array[3] = {key.x(), key.y(), key.z()};return qHashBits(array, 3 * sizeof(int), seed);}
}Qt3DRender::QAttribute *RenderAttributes::clone(Qt3DRender::QAttribute *from, Qt3DRender::QGeometry *parent)
{auto attribute = new Qt3DRender::QAttribute(parent);Qt3DRender::QBuffer *dataBuffer = new Qt3DRender::QBuffer(attribute);auto dataCopy = from->buffer()->data();dataCopy.detach();dataBuffer->setData(dataCopy);attribute->setAttributeType(from->attributeType());attribute->setBuffer(dataBuffer);attribute->setVertexBaseType(from->vertexBaseType());attribute->setVertexSize(from->vertexSize());attribute->setByteOffset(from->byteOffset());attribute->setByteStride(from->byteStride());attribute->setName(from->name());attribute->setCount(from->count());return attribute;
}ModelLoader::ModelLoader() {}int ModelLoader::loadModelFromFile(Qt3DCore::QEntity *rootEntity, QString filePath)
{Assimp::Importer importer;std::string modelPath = filePath.toStdString();const aiScene* sceneObjPtr = importer.ReadFile(modelPath,aiProcess_Triangulate | aiProcess_FlipUVs);// const aiScene* sceneObjPtr = importer.ReadFile(filePath,//                                                aiProcess_FlipUVs);if (!sceneObjPtr|| sceneObjPtr->mFlags == AI_SCENE_FLAGS_INCOMPLETE|| !sceneObjPtr->mRootNode){// 加载模型失败qDebug() << "Error:Model::loadModel, description: "<< importer.GetErrorString();return -1;}qDebug() << "load object:" << sceneObjPtr->mNumMeshes << sceneObjPtr->mNumAnimations;// 是否存在动画if(sceneObjPtr->HasAnimations()){aiAnimation* animation = sceneObjPtr->mAnimations[0];qDebug() << animation->mDuration << animation->mTicksPerSecond << animation->mName.C_Str();}// 是否存在材质if(sceneObjPtr->HasMaterials()){qDebug() << sceneObjPtr->mMaterials[0]->GetName().C_Str();}// 是否存在网格模型if(sceneObjPtr->HasMeshes()){qDebug() << sceneObjPtr->mMeshes[0]->mName.C_Str();}Qt3DCore::QEntity *modelEntity = new Qt3DCore::QEntity(rootEntity);// 修正一下坐标系Qt3DCore::QTransform *mTransform = new Qt3DCore::QTransform();mTransform->setRotationX(-90);modelEntity->addComponent(mTransform);return processNode(sceneObjPtr->mRootNode, sceneObjPtr, modelEntity);
}int ModelLoader::processNode(aiNode *node, const aiScene *scene, Qt3DCore::QEntity *entity)
{qDebug() << "node:" << node->mName.C_Str() << node->mNumMeshes << node->mNumChildren;Qt3DCore::QEntity *partModel = new Qt3DCore::QEntity(entity);Qt3DCore::QTransform *partTransform = new Qt3DCore::QTransform;aiMatrix4x4 mat = node->mTransformation;QMatrix4x4 qMat = QMatrix4x4(mat.a1, mat.a2, mat.a3, mat.a4,mat.b1, mat.b2, mat.b3, mat.b4,mat.c1, mat.c2, mat.c3, mat.c4,mat.d1, mat.d2, mat.d3, mat.d4);partTransform->setMatrix(qMat);partModel->addComponent(partTransform);partModel->setObjectName(node->mName.C_Str()); // 这个很有用,可以用来后期对节点进行查找// qDebug() << partTransform->rotationX()//          << partTransform->rotationY()//          << partTransform->rotationZ();// process each mesh located at the current nodefor (unsigned int i = 0; i < node->mNumMeshes; i++){// the node object only contains indices to index the actual objects in the scene.// the scene contains all the data, node is just to keep stuff organized (like relations between nodes).aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];processMesh(mesh, scene, partModel);}// after we've processed all of the meshes (if any) we then recursively process each of the children nodesfor (unsigned int i = 0; i < node->mNumChildren; i++){processNode(node->mChildren[i], scene, partModel);}return 0;
}int ModelLoader::processMesh(aiMesh *mesh, const aiScene *scene, Qt3DCore::QEntity *entity)
{qDebug() << "---> mesh:" << mesh->mName.C_Str();;Qt3DRender::QGeometry *geometry = new Qt3DRender::QGeometry(entity);Qt3DRender::QGeometryRenderer *geoRen = new Qt3DRender::QGeometryRenderer(entity);geoRen->setGeometry(geometry);geoRen->setPrimitiveType(Qt3DRender::QGeometryRenderer::Triangles);// 如果网格包含法线,则添加法线节点if(mesh->HasNormals()){// qDebug() << "has normal:" << mesh->mNumVertices;// 法线数据QVector<QVector3D> normals;for (unsigned int i = 0; i < mesh->mNumVertices; i++){aiVector3D normal = mesh->mNormals[i];normals << QVector3D(normal.x, normal.y, normal.z);}auto attr = RenderAttributes::create(normals, "vertexNormal", geometry);geometry->addAttribute(attr);}// 如果网格包含纹理坐标,则添加纹理坐标节点if(mesh->HasTextureCoords(0)){// qDebug() << "NumUVComponents :" << mesh->mNumUVComponents;// if(mesh->mNumUVComponents > 0)// {//     qDebug() << "has texture"//              << mesh->mTextureCoordsNames[0]->C_Str()//         ;// }QVector<QVector3D> textureCoordinates;for (unsigned int i = 0; i < mesh->mNumVertices; i++){aiVector3D texCoord = mesh->mTextureCoords[0][i];textureCoordinates << QVector3D(texCoord.x, texCoord.y, texCoord.z);}auto attrTC = RenderAttributes::create(textureCoordinates, Qt3DRender::QAttribute::defaultTextureCoordinateAttributeName(), geometry);geometry->addAttribute(attrTC);}// 将Assimp网格的顶点坐标添加到坐标节点// qDebug() << "vertices:" << mesh->mNumVertices;QVector<QVector3D> vertices;for (unsigned int i = 0; i < mesh->mNumVertices; i++){aiVector3D vertice = mesh->mVertices[i];vertices << QVector3D(vertice.x, vertice.y, vertice.z);}auto attrVeti = RenderAttributes::create(vertices, Qt3DRender::QAttribute::defaultPositionAttributeName(), geometry);geometry->addAttribute(attrVeti);geometry->setBoundingVolumePositionAttribute(attrVeti);// 将Assimp网格的面索引添加到面索引// qDebug() << "faces:" << mesh->mNumFaces;QVector<Triangle> faces;for (unsigned int i = 0; i < mesh->mNumFaces; i++){Triangle triFace;aiFace face = mesh->mFaces[i];triFace.vertexIndex1 = face.mIndices[0];triFace.vertexIndex2 = face.mIndices[1];triFace.vertexIndex3 = face.mIndices[2];faces << triFace;// for (unsigned int j = 0; j < face.mNumIndices; j++) // 填充面的索引// {//     faceSet->coordIndex.set1Value(faceSet->coordIndex.getNum(), face.mIndices[j]);// }}auto attrFace = RenderAttributes::create(faces, geometry);geometry->addAttribute(attrFace);// 设置材质if(mesh->mMaterialIndex >= 0){qDebug() << "set material";aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];// 创建材质节点// // 使用QMetalRoughMaterial时,貌似亮度有点不对// Qt3DExtras::QMetalRoughMaterial *qMaterial = new Qt3DExtras::QMetalRoughMaterial();// qMaterial->setMetalness(0.4);// qMaterial->setRoughness(0.55);Qt3DExtras::QDiffuseMapMaterial *qMaterial = new Qt3DExtras::QDiffuseMapMaterial();// 设置材质漫反射度float shiness;if (AI_SUCCESS == material->Get(AI_MATKEY_SHININESS, shiness)) {qDebug() << "shiness:" << shiness;// 使用 shiness 值qMaterial->setShininess(shiness);}// 设置材质漫反射颜色aiColor4D diffuseColor;if(AI_SUCCESS == material->Get(AI_MATKEY_COLOR_DIFFUSE, diffuseColor)){qDebug() << "rgb:" << diffuseColor.r << diffuseColor.g << diffuseColor.b;QColor tmpColor = QColor(diffuseColor.r * 255.0,diffuseColor.g * 255.0,diffuseColor.b * 255.0);qDebug() << tmpColor << QColor(255, 255, 255);// qMaterial->setBaseColor(tmpColor);QImage img(100, 100, QImage::Format_ARGB32);img.fill(tmpColor);MyQPaintedTextureImage *txtImg = new MyQPaintedTextureImage();txtImg->setImage(img);Qt3DRender::QTexture2D *txt2d = new Qt3DRender::QTexture2D();txt2d->addTextureImage(txtImg);// qMaterial->setBaseColor(QVariant::fromValue(txt2d));qMaterial->setDiffuse(txt2d);}// 设置环境颜色aiColor4D ambientColor;if(AI_SUCCESS == material->Get(AI_MATKEY_COLOR_AMBIENT, ambientColor)){QColor tmpColor = QColor(ambientColor.r, ambientColor.g, ambientColor.b, ambientColor.a);qDebug() << "ambient color:" << tmpColor;qMaterial->setAmbient(tmpColor);}else{qMaterial->setAmbient(QColor(128, 128, 128));}// 如果材质包含纹理,则创建纹理节点aiString texturePath; //Assimp texture file pathif(AI_SUCCESS == material->GetTexture(aiTextureType_DIFFUSE, 0, &texturePath)){qDebug() << "texture file:" << texturePath.C_Str();const aiTexture *embTexture = scene->GetEmbeddedTexture(texturePath.C_Str());if(embTexture) // 假如内嵌的纹理{qDebug() << "has embed img:"<< (char*)embTexture->achFormatHint<< embTexture->mFilename.C_Str()<< embTexture->mWidth << embTexture->mHeight;// 利用QPaintedTextureImage可以实现加载内存中的图片const unsigned char* data = reinterpret_cast<const unsigned char*>(embTexture->pcData);const size_t size = embTexture->mWidth;QByteArray imageData((char*)data, size);QImage img;if(img.loadFromData(imageData)){qDebug() << img;MyQPaintedTextureImage *txtImg = new MyQPaintedTextureImage();txtImg->setImage(img);Qt3DRender::QTexture2D *txt2d = new Qt3DRender::QTexture2D();txt2d->addTextureImage(txtImg);// qMaterial->setBaseColor(QVariant::fromValue(txt2d));qMaterial->setDiffuse(txt2d);}}else{qDebug() << "-----no embed img";}}else{qDebug() << "get texture fail" << material->GetTextureCount(aiTextureType_DIFFUSE);}entity->addComponent(qMaterial);}entity->addComponent(geoRen);return 0;
}

2.说明

2.1.调用

Qt3DExtras::Qt3DWindow *view = new Qt3DExtras::Qt3DWindow();
view->defaultFrameGraph()->setClearColor(QColor(QRgb(0x2b2b2b)));QString filePath = "myModel.glb";
Qt3DCore::QEntity *rootEntity = new Qt3DCore::QEntity();
ModelLoader::loadModelFromFile(rootEntity, filePath);view->setRootEntity(rootEntity);// 灯光及其他设置

2.2.关于贴图

假如使用QTextureImage的话,只能加载本地图片,但是参考【How can I load a QPaintedTextureImage into a QTextureMaterial?】,可以使用QPaintedTextureImage来加载内存中的图片。而glb/gltf文件本身包含了图片内容,读取glb文件时,图片内容已经加载到内存中了,因此QPaintedTextureImage更加适合。


参考
【Qt3DExample】
【How can I load a QPaintedTextureImage into a QTextureMaterial?】

相关文章:

使用Assimp加载glb/gltf文件,然后使用Qt3D来渲染

文章目录 1.代码2.说明2.1.调用2.2.关于贴图 1.代码 ModelLoader.h #ifndef MODELLOADER_H #define MODELLOADER_H#include <QObject> #include <Qt3DRender> #include <QVector3D> #include <QGeometry>#include <assimp/Importer.hpp> #incl…...

vue实现左侧数据拖拽到右侧区域,且左侧数据保留且左侧数据不能互相拖拽改变顺序

一、案例效果 二、案例代码 封装左侧抽屉 DrawerSearch.vue<template><div><mtd-form :model="formDrawerSearch" ref="formCustom" inline><mtd-form-item><mtd-inputtype="text"v-model="formDrawerSearch.ho…...

人工智能与机器学习原理精解【21】

文章目录 SVM求两线段上距离最近的两个点问题描述&#xff1a;距离函数&#xff1a;解法&#xff1a;具体步骤&#xff1a;特别注意&#xff1a;示例代码 SVM思想的介入1. **SVM 的基本思想**超平面&#xff1a; 2. **分类间隔&#xff08;Margin&#xff09;**1. **分类间隔的…...

【MySQL 01】数据库基础

目录 1.数据库是什么 2.基本操作 数据库服务器连接操作 数据库和数据库表的创建 服务器&#xff0c;数据库&#xff0c;表关系 数据逻辑存储 3.MySQL架构 4.SQL分类 5.存储引擎 1.数据库是什么 mysql&&mysqld&#xff1a; mysql&#xff1a;这通常指的是 MySQL …...

C语言字符学习中级使用库解决问题

学习C语言中的字符处理&#xff0c;对于初学者来说&#xff0c;理解字符的基本概念以及如何进行操作是非常重要的。字符处理是指对单个字符或一组字符&#xff08;字符串&#xff09;的操作。为了更好地理解&#xff0c;下面从基础开始介绍&#xff0c;并结合一些常用的函数和示…...

网络管理:网络故障排查指南

在现代IT环境中,网络故障是不可避免的。快速、有效地排查和解决网络故障是确保业务连续性和用户满意度的关键。本文将详细介绍网络故障排查的基本方法和步骤,确保内容通俗易懂,并配以代码示例和必要的图片说明。 一、网络故障排查的基本步骤 确认故障现象 确认用户报告的故…...

Springboot常见问题(bean找不到)

如图错误显示userMapper bean没有找到。 解决方案&#xff1a; mapper包位置有问题&#xff1a;因为SpringBoot默认的包扫描机制会扫描启动类所在的包同级文件和子包下的文件。注解问题&#xff1a; 比如没有加mapper注解 然而无论是UserMapper所在的包位置还是Mapper注解都是…...

架构设计笔记-5-软件工程基础知识

知识要点 按软件过程活动&#xff0c;将软件工具分为软件开发工具、软件维护工具、软件管理和软件支持工具。 软件开发工具&#xff1a;需求分析工具、设计工具、编码与排错工具。 软件维护工具&#xff1a;版本控制工具、文档分析工具、开发信息库工具、逆向工程工具、再工…...

Solidity——抽象合约和接口详解

&#x1f680;本系列文章为个人学习笔记&#xff0c;目的是巩固知识并记录我的学习过程及理解。文笔和排版可能拙劣&#xff0c;望见谅。 Solidity中的抽象合约和接口详解 目录 什么是抽象合约&#xff1f;抽象合约的语法接口&#xff08;Interface&#xff09;的定义接口的语…...

Fyne ( go跨平台GUI )中文文档-入门(一)

本文档注意参考官网(developer.fyne.io/) 编写, 只保留基本用法go代码展示为Go 1.16 及更高版本, ide为goland2021.2 这是一个系列文章&#xff1a; Fyne ( go跨平台GUI )中文文档-入门(一)-CSDN博客 Fyne ( go跨平台GUI )中文文档-Fyne总览(二)-CSDN博客 Fyne ( go跨平台GUI )…...

Google 扩展 Chrome 安全和隐私功能

过去一周&#xff0c;谷歌一直在推出新特性和功能&#xff0c;旨在让用户在 Chrome 上的桌面体验更加安全&#xff0c;最新的举措是扩展在多个设备上保存密钥的功能。 到目前为止&#xff0c;Chrome 网络用户只能将密钥保存到 Android 上的 Google 密码管理器&#xff0c;然后…...

css 缩放会变动的需要使用转换

position: fixed;top: 170px;left: 50%;transform: translate(-50%, -50%);...

(17)数据库neo4j数据备份

图数据库备份 假设图数据库安装位置&#xff1a;/root/shuzihua/neo4j-community-3.5.8 1.数据导出 进入/root/shuzihua/neo4j-community-3.5.8/bin目录&#xff1b;执行 neo4j stop 停止服务&#xff1b;/root/shuzihua/neo4j-community-3.5.8/data/databases/graph.db&#…...

从零开始学习Python

目录 从零开始学习Python 引言 环境搭建 安装Python解释器 选择IDE 基础语法 注释 变量和数据类型 变量命名规则 数据类型 运算符 算术运算符 比较运算符 逻辑运算符 输入和输出 控制流 条件语句 循环语句 for循环 while循环 循环控制语句 函数和模块 定…...

前端框架的对比和选择

在当今的前端开发领域&#xff0c;有多种流行的前端框架可供选择&#xff0c;如 Vue、React 和 Angular。以下是这些框架的对比以及 Vue 的优势&#xff1a; 一、React 特点&#xff1a; 声明式编程&#xff1a;使用 JSX 语法&#xff0c;使得组件的结构和行为更加清晰。虚拟…...

《机器学习》周志华-CH7(贝叶斯分类)

7.1贝叶斯决策论 对分类任务而言&#xff0c;在所有相关概率已知的理想情形下&#xff0c;贝叶斯决策论考虑如何基于这些概率核误判损失来选择最优的类别标记。 R ( x i ∣ x ) ∑ j 1 N λ i j P ( c j ∣ x ) \begin{equation} R(x_{i}|x)\sum_{j1}^{N}\lambda_{ij}P(c_{j}…...

【C/C++】错题记录(一)

题目一 这道题主要考查了用户对标准库函数的使用规则的理解。 选项 A&#xff0c;一般情况下用户调用标准库函数前不需要重新定义&#xff0c;该项说法错误。 选项 B&#xff0c;即使包含了标准库头文件及相关命名空间&#xff0c;也不允许用户重新定义标准库函数&#xff0c…...

【代码随想录训练营第42期 Day60打卡 - 图论Part10 - Bellman_ford算法系列运用

目录 一、Bellman_ford算法的应用 二、题目与题解 题目一&#xff1a;卡码网 94. 城市间货物运输 I 题目链接 题解&#xff1a;队列优化Bellman-Ford算法&#xff08;SPFA&#xff09; 题目二&#xff1a;卡码网 95. 城市间货物运输 II 题目链接 题解&#xff1a; 队列优…...

vue复制信息到粘贴框

npm install vue-clipboard2main.js文件引入 import VueClipboard from vue-clipboard2 Vue.use(VueClipboard)页面应用 copyInfo(info){let that thislet copyData 项目名称&#xff1a;${info.projectName}\n 用户名&#xff1a;${info.username}\n 初始密码&#xff1a;${…...

STM32基础笔记

第一章、STM32基本介绍 总内容 计算机技术简介环境安装、项目流程搭建最小系统时钟系统启动相关&#xff1a;启动文件、启动流程、启动方式GPIOUSARTNVIC: 外部中断_串口中断( DMA )TIMERADCDHT11: 单总线协议SPI : LCD屏 ## **1、计算机技术简介** 1.通用计算机/专用计算机…...

【深入学习Redis丨第六篇】Redis哨兵模式与操作详解

〇、前言 哨兵是一个分布式系统&#xff0c;你可以在一个架构中运行多个哨兵进程&#xff0c;这些进程使用流言协议来接收关于Master主服务器是否下线的信息&#xff0c;并使用投票协议来决定是否执行自动故障迁移&#xff0c;以及选择哪个Slave作为新的Master。 文章目录 〇、…...

开源项目 GAN 漫画风格化 UGATIT

开源项目&#xff1a;DataBall / UGATIT GitCode * 数据集 * [该项目制作的训练集的数据集下载地址(百度网盘 Password: gxl1 )](https://pan.baidu.com/s/1683TRcv3r3o7jSitq3VyYA) * 预训练模型 * [预训练模型下载地址(百度网盘 Password: khbg )](https://pan.ba…...

SegFormer网络结构的学习和重构

因为太多的博客并没有深入理解,本文是自己学习后加入自己深入理解的总结记录&#xff0c;方便自己以后查看。 segformer中encoder、decoder的详解。 学习前言 一起来学习Segformer的原理,如果有用的话&#xff0c;请记得点赞关注哦。 一、Segformer的网络结构图 网络结构&…...

ubuntu个人实用配置问题

记录两年前试图用Ubuntu作为自己的日常系统的实际情况 记录时间2022年8月26日 中间连输入法都安装不上。。哈哈又被自己笑到啦&#xff01; ubuntu 安装 使用市面上的各种 U 盘启动盘制作工具&#xff0c;下载 iso 文件之后将清空指定的 U 盘并制作为启动 U 盘&#xff0c;…...

Xk8s证书续期

Master节点 备份文件 cp -r /etc/kubernetes/ /etc/kubernetes-20211021-bak tar -cvzf kubernetes-20211021-bak.tar.gz /etc/kubernetes-20211021-bak/cp -r ~/.kube/ ~/.kube-20211021-bak tar -cvzf kube-20211021-bak.tar.gz ~/.kube-20211021-bakcp -r /var/lib/kube…...

仓颉编程入门2,启动HTTP服务

上一篇配置了仓颉sdk编译和运行环境&#xff0c;读取一个配置文件&#xff0c;并把配置文件简单解析了一下。 前面读取配置文件&#xff0c;使用File.readFrom()&#xff0c;这个直接把文件全部读取出来&#xff0c;返回一个字节数组。然后又创建一个字节流&#xff0c;给文件…...

Linux驱动开发初识

Linux驱动开发初识 文章目录 Linux驱动开发初识一、驱动的概念1.1 什么是驱动&#xff1a;1.2 驱动的分类&#xff1a; 二、设备的概念2.1 主设备号&次设备号&#xff1a;2.2 设备号的作用&#xff1a; 三、设备驱动整体调用过程3.1 上层用户操控设备的流程&#xff1a;3.2…...

前端面试题(三)

11. Web API 面试题 如何使用 fetch 发起网络请求&#xff1f; fetch 是现代浏览器中用于发起网络请求的原生 API。它返回一个 Promise&#xff0c;默认情况下使用 GET 请求&#xff1a;fetch(https://api.example.com/data).then(response > response.json()).then(data &g…...

骨传导耳机哪个牌子最好用?实测五大实用型骨传导耳机分析!

在快节奏的现代生活中&#xff0c;耳机已成为我们不可或缺的伴侣。无论是在通勤路上、运动时&#xff0c;还是在安静的图书馆&#xff0c;耳机都能为我们提供一片属于自己的音乐天地。然而&#xff0c;长时间使用传统耳机可能会对听力造成损害&#xff0c;尤其是在高音量下。因…...

18.1 k8s服务组件之4大黄金指标讲解

本节重点介绍 : 监控4大黄金指标 Latency&#xff1a;延时Utilization&#xff1a;使用率Saturation&#xff1a;饱和度Errors&#xff1a;错误数或错误率 apiserver指标 400、500错误qps访问延迟队列深度 etcd指标kube-scheduler和kube-controller-manager 监控4大黄金指标 …...