Qt 提供了完善的 OpenGL 集成方案,使开发者能够在 Qt 应用中高效开发 3D 图形应用。通过 Qt 的 OpenGL 模块,可简化 OpenGL 上下文管理、窗口渲染和跨平台适配,同时结合现代 OpenGL 特性(如着色器、顶点缓冲、纹理等)实现高性能 3D 图形渲染。本文从基础环境搭建到高级 3D 渲染,全面解析 Qt 与 OpenGL 的集成开发。

一、Qt 中 OpenGL 的核心组件

Qt 对 OpenGL 的封装主要通过以下类实现,它们构成了 3D 开发的基础:

类名作用
QOpenGLWidget继承自 QWidget,提供 OpenGL 渲染上下文和窗口,是 3D 渲染的主载体
QOpenGLFunctions封装 OpenGL 函数(如 glClear、glDrawArrays 等),避免手动加载函数指针
QOpenGLShader管理单个着色器(顶点着色器、片段着色器等)的编译
QOpenGLShaderProgram链接多个着色器为着色器程序,用于渲染时的可编程管线控制
QOpenGLBuffer封装 OpenGL 缓冲对象(VBO/VAO/EBO),管理顶点数据存储
QOpenGLTexture封装 OpenGL 纹理对象,支持加载图像并绑定到着色器

二、基础环境搭建:第一个 3D 窗口

使用 QOpenGLWidget 搭建最基础的 OpenGL 渲染环境,核心是重写其三个关键虚函数:

1. 核心函数说明
  • initializeGL():初始化 OpenGL 上下文(如设置清除颜色、启用深度测试、编译着色器等),仅在窗口创建时调用一次。
  • resizeGL(int w, int h):窗口大小变化时调用,用于更新视口和投影矩阵。
  • paintGL():负责实际渲染逻辑(如绘制几何体、更新模型矩阵等),每次窗口刷新时调用。
2. 示例:创建空白 OpenGL 窗口
// main.cpp
#include <QApplication>
#include <QOpenGLWidget>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>// 自定义 OpenGL 窗口类
class MyGLWidget : public QOpenGLWidget, protected QOpenGLFunctions {Q_OBJECT
public:MyGLWidget(QWidget *parent = nullptr) : QOpenGLWidget(parent) {}protected:// 初始化 OpenGL 环境void initializeGL() override {initializeOpenGLFunctions();  // 初始化 OpenGL 函数glClearColor(0.2f, 0.3f, 0.3f, 1.0f);  // 设置清除颜色(深灰)glEnable(GL_DEPTH_TEST);  // 启用深度测试(3D 渲染必备)}// 窗口大小变化时更新视口void resizeGL(int w, int h) override {glViewport(0, 0, w, h);  // 设置视口:从(0,0)到(w,h)}// 渲染逻辑void paintGL() override {glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);  // 清除颜色和深度缓冲}
};int main(int argc, char *argv[]) {QApplication a(argc, argv);MyGLWidget w;w.setWindowTitle("Qt OpenGL 基础窗口");w.resize(800, 600);w.show();return a.exec();
}#include "main.moc"

运行后会显示一个深灰色背景的窗口,这是 3D 渲染的基础画布。

三、绘制 3D 几何体:顶点数据与着色器

现代 OpenGL 依赖着色器(Shader)进行渲染,需定义顶点数据并通过着色器程序将其绘制到屏幕上。

1. 定义顶点数据与缓冲

3D 几何体由顶点组成,每个顶点包含位置、颜色、纹理坐标等属性。通过顶点缓冲对象(VBO)和顶点数组对象(VAO)管理这些数据:

// 在 MyGLWidget 中添加成员变量
private:QOpenGLShaderProgram *shaderProgram;  // 着色器程序unsigned int VAO, VBO;  // 顶点数组对象和顶点缓冲对象float vertices[18] = {  // 三角形顶点数据(3个顶点,每个包含x,y,z坐标)-0.5f, -0.5f, 0.0f,  // 顶点10.5f, -0.5f, 0.0f,  // 顶点20.0f,  0.5f, 0.0f   // 顶点3};
2. 编写着色器程序

着色器分为顶点着色器(处理顶点位置)和片段着色器(处理像素颜色),需在 initializeGL 中加载并编译:

顶点着色器(vertexShader.vert)

#version 330 core
layout (location = 0) in vec3 aPos;  // 顶点位置输入void main() {gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);  // 输出顶点位置
}

片段着色器(fragmentShader.frag)

#version 330 core
out vec4 FragColor;  // 输出像素颜色void main() {FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);  // 橙色
}
3. 初始化缓冲与着色器

initializeGL 中初始化 VAO、VBO 和着色器程序:

void MyGLWidget::initializeGL() {initializeOpenGLFunctions();// 编译着色器shaderProgram = new QOpenGLShaderProgram(this);// 加载并编译顶点着色器if (!shaderProgram->addShaderFromSourceFile(QOpenGLShader::Vertex, ":/vertexShader.vert")) {qDebug() << "顶点着色器编译错误:" << shaderProgram->log();}// 加载并编译片段着色器if (!shaderProgram->addShaderFromSourceFile(QOpenGLShader::Fragment, ":/fragmentShader.frag")) {qDebug() << "片段着色器编译错误:" << shaderProgram->log();}// 链接着色器程序if (!shaderProgram->link()) {qDebug() << "着色器链接错误:" << shaderProgram->log();}// 初始化 VAO 和 VBOglGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);// 绑定 VAO(后续操作会记录到 VAO 中)glBindVertexArray(VAO);// 绑定 VBO 并传入顶点数据glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);// 配置顶点属性(位置属性)glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(float), (void*)0);glEnableVertexAttribArray(0);  // 启用位置属性// 解绑缓冲(可选,避免后续误操作)glBindBuffer(GL_ARRAY_BUFFER, 0);glBindVertexArray(0);// 初始化其他状态glClearColor(0.2f, 0.3f, 0.3f, 1.0f);glEnable(GL_DEPTH_TEST);
}
4. 绘制几何体

paintGL 中绘制三角形:

void MyGLWidget::paintGL() {glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 使用着色器程序shaderProgram->bind();// 绑定 VAO(包含顶点数据和属性配置)glBindVertexArray(VAO);// 绘制三角形(3个顶点)glDrawArrays(GL_TRIANGLES, 0, 3);// 解绑glBindVertexArray(0);shaderProgram->release();
}

运行后会在深灰色背景上显示一个橙色三角形,这是 3D 渲染的基础形态。

四、3D 场景进阶:矩阵变换与相机控制

要实现真正的 3D 效果,需通过矩阵变换(模型、视图、投影矩阵)控制几何体的位置、角度和透视,并通过相机控制实现场景漫游。

1. 矩阵变换基础
  • 模型矩阵(Model Matrix):控制几何体的平移、旋转、缩放。
  • 视图矩阵(View Matrix):模拟相机位置和朝向(如移动相机查看不同角度)。
  • 投影矩阵(Projection Matrix):定义透视效果(如近大远小)。

Qt 中可通过 QMatrix4x4 处理矩阵运算,或集成 glm(OpenGL Mathematics)库(更强大的矩阵工具)。

2. 示例:3D 立方体与相机控制

步骤 1:定义立方体顶点数据(包含位置和纹理坐标):

float vertices[] = {// 位置(x,y,z)            // 纹理坐标(s,t)-0.5f, -0.5f, -0.5f,  0.0f, 0.0f,0.5f, -0.5f, -0.5f,  1.0f, 0.0f,0.5f,  0.5f, -0.5f,  1.0f, 1.0f,// ... 其他5个面的顶点(共36个顶点,立方体6个面,每个面2个三角形)
};

步骤 2:添加矩阵uniform变量到着色器
顶点着色器需接收矩阵变换:

#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec2 aTexCoord;out vec2 TexCoord;  // 传递纹理坐标到片段着色器uniform mat4 model;    // 模型矩阵
uniform mat4 view;     // 视图矩阵
uniform mat4 projection; // 投影矩阵void main() {gl_Position = projection * view * model * vec4(aPos, 1.0f);TexCoord = aTexCoord;
}

步骤 3:初始化矩阵并传递到着色器
resizeGL 中初始化投影矩阵,在 paintGL 中更新模型和视图矩阵:

void MyGLWidget::resizeGL(int w, int h) {glViewport(0, 0, w, h);// 透视投影矩阵(fov=45°,宽高比=w/h,近平面=0.1,远平面=100)projection.setToIdentity();projection.perspective(45.0f, (float)w/h, 0.1f, 100.0f);
}void MyGLWidget::paintGL() {glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);shaderProgram->bind();// 模型矩阵:旋转立方体QMatrix4x4 model;model.rotate(rotationAngle, 1.0f, 1.0f, 0.0f);  // 绕(1,1,0)轴旋转shaderProgram->setUniformValue("model", model);// 视图矩阵:相机位置(在(0,0,3)处,看向原点)QMatrix4x4 view;view.translate(0.0f, 0.0f, -3.0f);  // 相机后移3个单位shaderProgram->setUniformValue("view", view);// 投影矩阵shaderProgram->setUniformValue("projection", projection);// 绘制立方体(36个顶点)glBindVertexArray(VAO);glDrawArrays(GL_TRIANGLES, 0, 36);// 解绑glBindVertexArray(0);shaderProgram->release();// 旋转动画(每帧更新角度)rotationAngle += 0.5f;update();  // 触发重绘
}

步骤 4:鼠标交互控制相机
通过重写鼠标事件实现旋转、缩放:

void MyGLWidget::mousePressEvent(QMouseEvent *event) {lastMousePos = event->pos();  // 记录鼠标按下位置
}void MyGLWidget::mouseMoveEvent(QMouseEvent *event) {if (event->buttons() & Qt::LeftButton) {// 计算鼠标移动偏移int dx = event->x() - lastMousePos.x();int dy = event->y() - lastMousePos.y();// 更新相机旋转角度(示例:简单映射)cameraYaw += dx * 0.5f;cameraPitch += dy * 0.5f;lastMousePos = event->pos();update();}
}

五、纹理与光照:提升真实感

纹理(贴图像到几何体表面)和光照(模拟光源效果)是 3D 场景真实感的核心。

1. 纹理映射

步骤 1:加载纹理图像
使用 QOpenGLTexture 加载图片并配置:

void MyGLWidget::initializeGL() {// ... 其他初始化// 加载纹理QOpenGLTexture *texture = new QOpenGLTexture(QImage(":/container.jpg").mirrored());texture->setMinificationFilter(QOpenGLTexture::LinearMipMapLinear);  // 缩小过滤texture->setMagnificationFilter(QOpenGLTexture::Linear);  // 放大过滤texture->setWrapMode(QOpenGLTexture::Repeat);  // 纹理环绕方式shaderProgram->setUniformValue("ourTexture", 0);  // 绑定到纹理单元0
}

步骤 2:在片段着色器中应用纹理

#version 330 core
in vec2 TexCoord;  // 接收纹理坐标
out vec4 FragColor;uniform sampler2D ourTexture;  // 纹理采样器void main() {FragColor = texture(ourTexture, TexCoord);  // 采样纹理颜色
}
2. 基础光照

通过添加光源和材质属性模拟漫反射和镜面反射:

// 顶点着色器(输出法向量和世界坐标)
#version 330 core
layout (location = 0) in vec3 aPos;
layout (location = 1) in vec3 aNormal;  // 法向量out vec3 FragPos;  // 世界空间中的顶点位置
out vec3 Normal;   // 法向量uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main() {FragPos = vec3(model * vec4(aPos, 1.0));Normal = mat3(transpose(inverse(model))) * aNormal;  // 修正法向量(考虑模型变换)gl_Position = projection * view * vec4(FragPos, 1.0);
}// 片段着色器(计算漫反射和镜面反射)
#version 330 core
in vec3 FragPos;
in vec3 Normal;out vec4 FragColor;uniform vec3 lightPos;    // 光源位置
uniform vec3 viewPos;     // 相机位置
uniform vec3 lightColor;  // 光源颜色
uniform vec3 objectColor; // 物体颜色void main() {// 环境光float ambientStrength = 0.1f;vec3 ambient = ambientStrength * lightColor;// 漫反射vec3 norm = normalize(Normal);vec3 lightDir = normalize(lightPos - FragPos);float diff = max(dot(norm, lightDir), 0.0);vec3 diffuse = diff * lightColor;// 镜面反射float specularStrength = 0.5f;vec3 viewDir = normalize(viewPos - FragPos);vec3 reflectDir = reflect(-lightDir, norm);float spec = pow(max(dot(viewDir, reflectDir), 0.0), 32);  // 32是高光系数vec3 specular = specularStrength * spec * lightColor;// 最终颜色vec3 result = (ambient + diffuse + specular) * objectColor;FragColor = vec4(result, 1.0);
}

六、高级应用:模型加载与帧缓冲

1. 加载复杂 3D 模型

使用 Assimp(Open Asset Import Library)加载 OBJ、FBX 等格式的模型,Qt 中可通过 QOpenGLWidget 结合 Assimp 实现:

// 伪代码:使用Assimp加载模型
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>void loadModel(const std::string &path) {Assimp::Importer importer;const aiScene *scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);  // 三角化、翻转UVif (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {qDebug() << "Assimp错误:" << importer.GetErrorString();return;}// 递归处理场景中的所有网格...
}
2. 帧缓冲(FBO)与离屏渲染

使用帧缓冲实现高级效果(如阴影、后期处理):

// 初始化帧缓冲
void initFramebuffer() {glGenFramebuffers(1, &FBO);glBindFramebuffer(GL_FRAMEBUFFER, FBO);// 创建颜色附件(纹理)glGenTextures(1, &textureColorbuffer);glBindTexture(GL_TEXTURE_2D, textureColorbuffer);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, 800, 600, 0, GL_RGB, GL_UNSIGNED_BYTE, NULL);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, textureColorbuffer, 0);// 检查帧缓冲完整性if (glCheckFramebufferStatus(GL_FRAMEBUFFER) != GL_FRAMEBUFFER_COMPLETE)qDebug() << "帧缓冲不完整!";glBindFramebuffer(GL_FRAMEBUFFER, 0);  // 解绑
}// 离屏渲染到帧缓冲,再将纹理绘制到屏幕
void paintGL() {// 1. 渲染到帧缓冲glBindFramebuffer(GL_FRAMEBUFFER, FBO);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 绘制场景...glBindFramebuffer(GL_FRAMEBUFFER, 0);// 2. 渲染帧缓冲纹理到屏幕(全屏四边形)glClear(GL_COLOR_BUFFER_BIT);screenShader->bind();glBindVertexArray(screenVAO);glBindTexture(GL_TEXTURE_2D, textureColorbuffer);glDrawArrays(GL_TRIANGLES, 0, 6);
}

七、性能优化与注意事项

  1. 顶点缓冲优化:使用索引缓冲(EBO)减少重复顶点数据,降低内存占用。
  2. 状态管理:减少 OpenGL 状态切换(如绑定不同 VAO、纹理),提高渲染效率。
  3. 着色器优化:简化片段着色器逻辑,避免复杂计算;使用着色器缓存减少编译时间。
  4. 调试技巧
    • 启用 OpenGL 调试输出(glDebugMessageCallback)。
    • 使用 QOpenGLDebugLogger 捕获 Qt 中的 OpenGL 错误。
    • 借助 RenderDoc 等工具调试 3D 渲染流程。
  5. 跨平台适配:不同平台的 OpenGL 版本支持不同,需通过 QSurfaceFormat 指定版本(如 OpenGL 3.3 核心模式)。

八、总结

Qt 与 OpenGL 的集成简化了 3D 应用开发的底层细节(如窗口管理、上下文创建),使开发者可专注于渲染逻辑。通过 QOpenGLWidget、着色器程序、矩阵变换和相机控制,可实现从简单几何体到复杂 3D 场景的渲染。结合纹理、光照、模型加载和帧缓冲等技术,能开发出具有专业级真实感的 3D 应用,适用于游戏、仿真、CAD 等领域。掌握这些技术后,可进一步探索 Vulkan(Qt 也支持)等更现代的图形 API。

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

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【NLP舆情分析】基于python微博舆情分析可视化系统(flask+pandas+echarts) 视频教程 - 热词评论查询功能实现

大家好&#xff0c;我是java1234_小锋老师&#xff0c;最近写了一套【NLP舆情分析】基于python微博舆情分析可视化系统(flaskpandasecharts)视频教程&#xff0c;持续更新中&#xff0c;计划月底更新完&#xff0c;感谢支持。今天讲解热词评论查询功能实现 视频在线地址&#…

使用 Google Earth 的 DEM — 教程。

数字高程模型 (DEM)描绘了已知高程点之间的表面高程。本教程将向您展示如何使用 Google Earth 的高程数据生成 DEM。在当今世界&#xff0c;DEM 主要用于 GIS 应用。 当然&#xff0c;我们可以从美国地质调查局 (USGS) 网站下载数字高程模型 (DEM)。但如果我们想知道某个地点的…

在 UniApp 中实现中间凸起 TabBar 的完整指南

如何在 UniApp 中设置中间 TabBar 凸起效果 在移动应用开发中&#xff0c;TabBar 是常见的导航组件&#xff0c;而中间凸起的 TabBar 按钮则是一种流行的设计风格&#xff0c;常用于突出重要功能&#xff08;如发布、拍照等&#xff09;。UniApp 提供了 midButton 属性&#xf…

微观低代码

今日去深圳的一家工厂给客户做培训&#xff0c;主要培训内容为低代码产品的二开和功能演示。客户使用了20年的ERP和OA系统&#xff0c;目前想对接到低代码平台。客户目前想实现的主要功能是&#xff0c;对接OA的单点登录&#xff0c;把ERP的功能迁移到低代码平台上来工厂规模比…

Linux进程控制:掌握系统的核心脉络

Linux进程控制&#xff1a;掌握系统的核心脉络 在 Linux 系统中&#xff0c;进程控制是系统运行的核心机制之一。无论是日常的命令行操作&#xff0c;还是复杂的后台服务运行&#xff0c;都离不开对进程的管理和控制。本文将深入探讨 Linux 进程控制的相关知识&#xff0c;帮助…

4N90-ASEMI电机控制专用4N90

编辑&#xff1a;LL4N90-ASEMI电机控制专用4N90型号&#xff1a;4N90品牌&#xff1a;ASEMI封装&#xff1a;ITO-220ABRDS(on):3.60Ω批号&#xff1a;最新引脚数量&#xff1a;3封装尺寸&#xff1a;如图特性&#xff1a;N沟道MOS管工作结温&#xff1a;-55℃~150℃一、卓越性…

Java 笔记 lambda

✅Lambda 基本语法 (parameters) -> expression 或 (parameters) -> { statements }// 无参数 Runnable r () -> System.out.println("Hello");// 单个参数&#xff08;小括号可省略&#xff09; Consumer<String> c s -> System.out.println(s…

安全风险监测平台:被动应对向主动预防的转变

一、智能识别预警系统安全风险监测平台通过部署多维度感知网络&#xff0c;实现对各类安全隐患的智能识别与实时预警。系统采用深度学习算法&#xff0c;对人员行为、设备状态、环境参数等进行全天候监测分析&#xff0c;建立动态风险评估模型。当检测到异常情况时&#xff0c;…

图片查重从设计到实现(2)Milvus安装准备etcd介绍、应用场景及Docker安装配置

etcd作用、应用场景及Docker安装配置 在分布式向量数据库 Milvus 的架构中&#xff0c;etcd 扮演着至关重要的角色。Milvus 用于存储和管理海量向量数据&#xff0c;支持高效的相似性搜索等操作&#xff0c;而其分布式集群的正常运行高度依赖元数据的一致性和可靠性&#xff0c…

零弹窗干扰的贪吃蛇游戏,下载即玩

软件介绍 在寻找贪吃蛇游戏的过程中&#xff0c;我发现了一款PC端版本&#xff0c;无需登录即可直接使用&#xff0c;完全符合我的需求。 使用优势 这款软件最大的亮点在于完全免费&#xff0c;没有任何广告和弹窗干扰&#xff0c;支持完全离线运行&#xff0c;让用户能够专注…

excel2013VBA开发access mdb数据库系统的一点经验分享

最近&#xff0c;自己从网盘里重新下载了过去保存的vba开发资料&#xff0c;就顺手研究起了如何能通过excel203结合access 2013 mdb数据库系统开发个VBA小系统。过简单一说说了&#xff01;接说干货经验分享吧&#xff0c;1、俺先在mdb数据库中建了一个有自动编号字段的数据表&…

我们能否承担微服务带来的复杂性和运维成本?

坦率地说&#xff0c;并非所有团队都应该&#xff0c;承担微服务带来的复杂性和运维成本。在做出决定前&#xff0c;我们必须进行自我评估。 以下是评估是否能承担微服务成本需要考虑的关键方面&#xff1a; 一、 复杂性带来的挑战 (Complexity Challenges):分布式系统固有复杂…

HCIP--MGRE实验

一、实验拓扑二、配置思路1、建立拓扑&#xff0c;配置IP&#xff0c;配置缺省路由是公网通畅2、路由器R1-R5,R2-R5,R3-R5之间都是串线链接&#xff0c;由于华为路由器默认的串线协议为PPP&#xff0c;因此根据实验要求&#xff0c;R1-R5,R2-R5之间直接进行单向认证&#xff0c…

数字孪生映射探索驱动的具身导航!MorphoNavi:面向对象映射的空地机器人导航

作者&#xff1a; Sausar Karaf, Mikhail Martynov, Oleg Sautenkov, Zhanibek Darush, Dzmitry Tsetserukou单位&#xff1a;俄罗斯斯科尔科沃科学技术研究院智能空间机器人实验室论文标题&#xff1a;MorphoNavi: Aerial-Ground Robot Navigation with Object Oriented Mappi…

统计与大数据分析与数学金融课程解析

CDA数据分析师证书含金量高&#xff0c;适应了未来数字化经济和AI发展趋势&#xff0c;难度不高&#xff0c;行业认可度高&#xff0c;对于找工作很有帮助。一、课程体系对比矩阵维度统计与大数据分析数学金融交叉领域数学基础概率论(90%)随机过程(85%)线性代数(100%)核心工具P…

整蛊小程序:关机程序(C语言)

整蛊小程序&#xff1a;关机程序&#xff08;C语言) 跟着潼心走&#xff0c;轻松拿捏C语言&#xff0c;困惑通通走&#xff0c;一去不回头~欢迎开始今天的学习内容&#xff0c;你的支持就是博主最大的动力。 目录 整蛊小程序&#xff1a;关机程序&#xff08;C语言) 程序内容…

PHP框架之Laravel框架教程:1. laravel搭建

1. laravel搭建 本教程适合有php基础的同学学习 安装方式一&#xff1a; 使用 Laravel 安装器&#xff1a; 需要本地先安装PHP 和 Composer&#xff0c;这个自行安装下。 安装完成后验证方式&#xff1a; // 终端输入&#xff0c;就可以看到结果 php --version composer --vers…

HMC7044芯片配置(图文+解析+代码仿真)

详细代码及仿真源文件已同步上传至个人主页资源&#xff08;原创不易&#xff0c;转载请注明出处&#xff09; 目录 模块图 代码实现 时序图 仿真图 HMC7044介绍 一、概述 HMC7044是带有 JESD204B 接口的高性能、3.2 GHz、14 路输出抖动衰减器&#xff0c;提供 14 路低噪…

Dify开发教程笔记(一): 文件及系统参数变量说明及使用

开始 Copy page 定义“开始” 节点是每个工作流应用&#xff08;Chatflow / Workflow&#xff09;必备的预设节点&#xff0c;为后续工作流节点以及应用的正常流转提供必要的初始信息&#xff0c;例如应用使用者所输入的内容、以及上传的文件等。 配置节点在开始节点的设置页…

iOS 26,双版本更新来了

7 月 25 日&#xff0c;苹果终于给用户推送了 iOS 26 的首个公测版本。参与了公测版计划的小伙伴在软件更新页面选择 iOS 26 Public Beta 就能升级 iOS 26 的公测版。同时苹果还推送了 iOS 26 Beta 4 的第二个版本 。也就是说之前已经升级了 iOS 26 Beta 4 的小伙伴&#xff0c…