【小沐学QT】QT学习之OpenGL开发笔记

文章目录

  • 1、简介
  • 2、Qt + QOpenGLWidget + gl函数
  • 3、Qt + QOpenGLWidget + qt函数
  • 4、Qt + QOpenGLWindow
  • 5、Qt + glut
  • 6、Qt + glfw
  • 结语

1、简介

Qt提供了与OpenGL实现集成的支持,使开发人员有机会在更传统的用户界面的同时显示硬件加速的3D图形。

Qt有两种主要的UI开发方法:QtQuick和QtWidgets。它们的存在是为了支持不同类型的用户界面,并建立在针对每种类型进行了优化的独立图形引擎上。
在这里插入图片描述

可以将在OpenGL图形API中编写的代码与Qt中的这两种用户界面类型结合起来。当应用程序有自己的OpenGL相关代码时,或者当它与基于OpenGL的第三方渲染器集成时,这可能很有用。

Qt OpenGL模块包含方便类,使这种类型的集成更容易、更快。

QOpenGLWidget提供了三个方便的虚拟函数,您可以在子类中重新实现这些函数来执行典型的OpenGL任务:

  • paintGL()-渲染OpenGL场景。每当需要更新小部件时调用。
  • resizeGL()-设置OpenGL视口、投影等。每当小部件被调整大小时(以及当它第一次显示时,因为所有新创建的小部件都会自动获得调整大小事件),都会调用它。
  • initializeGL()-设置OpenGL资源和状态。在第一次调用resizeGL()或paintGL()之前调用一次。

最简单的QOpenGLWidget子类可能如下所示:

class MyGLWidget : public QOpenGLWidget
{
public:MyGLWidget(QWidget *parent) : QOpenGLWidget(parent) { }protected:void initializeGL() override{// Set up the rendering context, load shaders and other resources, etc.:QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();f->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);...}void resizeGL(int w, int h) override{// Update projection matrix and other size related settings:m_projection.setToIdentity();m_projection.perspective(45.0f, w / float(h), 0.01f, 100.0f);...}void paintGL() override{// Draw the scene:QOpenGLFunctions *f = QOpenGLContext::currentContext()->functions();f->glClear(GL_COLOR_BUFFER_BIT);...}};

或者,可以通过从QOpenGLFunctions派生来避免每个OpenGL调用的前缀:

class MyGLWidget : public QOpenGLWidget, protected QOpenGLFunctions
{...void initializeGL() override{initializeOpenGLFunctions();glClearColor(...);...}...
};

2、Qt + QOpenGLWidget + gl函数

  • untitled4.pro
QT       += core guigreaterThan(QT_MAJOR_VERSION, 4): QT += widgetsCONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGSSOURCES += \main.cpp \qopenglwidgettest.cppHEADERS += \qopenglwidgettest.hFORMS += \qopenglwidgettest.ui# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += targetRESOURCES += \res.qrc
  • main.cpp
#include "qopenglwidgettest.h"
#include <QApplication>int main(int argc, char *argv[])
{QApplication a(argc, argv);QOpenGLWidgetTest w;w.show();return a.exec();
}
  • qopenglwidgettest.h
#ifndef QOPENGLWIDGETTEST_H
#define QOPENGLWIDGETTEST_H#include <QOpenGLWidget>
#include <QOpenGLFunctions_3_3_Core>
#include <QOpenGLShaderProgram>QT_BEGIN_NAMESPACE
namespace Ui { class QOpenGLWidgetTest; }
QT_END_NAMESPACEclass QOpenGLWidgetTest : public QOpenGLWidget, protected /*QOpenGLExtraFunctions*/QOpenGLFunctions_3_3_Core
{Q_OBJECTpublic:QOpenGLWidgetTest(QWidget *parent = nullptr);~QOpenGLWidgetTest();protected:virtual void initializeGL();virtual void resizeGL(int w, int h);virtual void paintGL();private:Ui::QOpenGLWidgetTest *ui;QOpenGLShaderProgram shaderProgram;
};
#endif // QOPENGLWIDGETTEST_H
  • qopenglwidgettest.cpp
#include "qopenglwidgettest.h"
#include "ui_qopenglwidgettest.h"static GLuint VBO, VAO, EBO;QOpenGLWidgetTest::QOpenGLWidgetTest(QWidget *parent): QOpenGLWidget(parent), ui(new Ui::QOpenGLWidgetTest)
{ui->setupUi(this);
}QOpenGLWidgetTest::~QOpenGLWidgetTest()
{delete ui;glDeleteVertexArrays(1, &VAO);glDeleteBuffers(1, &VBO);glDeleteBuffers(1, &EBO);
}void QOpenGLWidgetTest::initializeGL(){this->initializeOpenGLFunctions();bool success = shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/new/prefix1/triangle.vert");if (!success) {qDebug() << "shaderProgram addShaderFromSourceFile failed!" << shaderProgram.log();return;}success = shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/new/prefix1/triangle.frag");if (!success) {qDebug() << "shaderProgram addShaderFromSourceFile failed!" << shaderProgram.log();return;}success = shaderProgram.link();if(!success) {qDebug() << "shaderProgram link failed!" << shaderProgram.log();}//VAO,VBO数据部分float vertices[] = {0.5f,  0.5f, 0.0f,  // top right0.5f, -0.5f, 0.0f,  // bottom right-0.5f, -0.5f, 0.0f,  // bottom left-0.5f,  0.5f, 0.0f   // top left};unsigned int indices[] = {  // note that we start from 0!0, 1, 3,  // first Triangle1, 2, 3   // second Triangle};glGenVertexArrays(1, &VAO);glGenBuffers(1, &VBO);glGenBuffers(1, &EBO);// bind the Vertex Array Object first, then bind and set vertex buffer(s), and then configure vertex attributes(s).glBindVertexArray(VAO);glBindBuffer(GL_ARRAY_BUFFER, VBO);glBufferData(GL_ARRAY_BUFFER, sizeof(vertices), vertices, GL_STATIC_DRAW);  //顶点数据复制到缓冲glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indices), indices, GL_STATIC_DRAW);glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 3 * sizeof(GLfloat), (void*)0);//告诉程序如何解析顶点数据glEnableVertexAttribArray(0);glBindBuffer(GL_ARRAY_BUFFER, 0);//取消VBO的绑定, glVertexAttribPointer已经把顶点属性关联到顶点缓冲对象了//    remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.
//    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);//    You can unbind the VAO afterwards so other VAO calls won't accidentally modify this VAO, but this rarely happens. Modifying other
//    VAOs requires a call to glBindVertexArray anyways so we generally don't unbind VAOs (nor VBOs) when it's not directly necessary.glBindVertexArray(0);   //取消VAO绑定
}void QOpenGLWidgetTest::resizeGL(int w, int h){glViewport(0, 0, w, h);
}void QOpenGLWidgetTest::paintGL(){glClearColor(0.5f, 0.5f, 0.5f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);shaderProgram.bind();glBindVertexArray(VAO); 
//    glDrawArrays(GL_TRIANGLES, 0, 6);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);shaderProgram.release();
}
  • triangle.vert
#version 330 core
layout(location = 0) in vec3 aPos;void main(){gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0f);
}
  • triangle.frag
#version 330 core
out vec4 FragColor;void main(){FragColor = vec4(1.0f, 0.5f, 0.2f, 1.0f);
}

运行如下:
在这里插入图片描述

3、Qt + QOpenGLWidget + qt函数

  • qtfunctionwidget.h
#ifndef QTFUNCTIONWIDGET_H
#define QTFUNCTIONWIDGET_H#include <QOpenGLWidget>
#include <QOpenGLShader>
#include <QOpenGLShaderProgram>
#include <QDebug>
#include <QOpenGLFunctions>
#include <QOpenGLVertexArrayObject>
#include <QOpenGLBuffer>class QtFunctionWidget : public QOpenGLWidget, protected QOpenGLFunctions
{
public:QtFunctionWidget(QWidget *parent = nullptr);~QtFunctionWidget() Q_DECL_OVERRIDE;protected:virtual void initializeGL() Q_DECL_OVERRIDE;virtual void resizeGL(int w, int h) Q_DECL_OVERRIDE;virtual void paintGL() Q_DECL_OVERRIDE;private:QOpenGLShaderProgram shaderProgram;QOpenGLBuffer vbo, ebo;QOpenGLVertexArrayObject vao;
};#endif // QTFUNCTIONWIDGET_H
  • qtfunctionwidget.cpp
#include "QtFunctionWidget.h"
#include <QFile>QtFunctionWidget::QtFunctionWidget(QWidget *parent) : QOpenGLWidget (parent),vbo(QOpenGLBuffer::VertexBuffer),ebo(QOpenGLBuffer::IndexBuffer)
{}QtFunctionWidget::~QtFunctionWidget(){makeCurrent();vbo.destroy();ebo.destroy();vao.destroy();doneCurrent();
}void QtFunctionWidget::initializeGL(){this->initializeOpenGLFunctions();bool success = shaderProgram.addShaderFromSourceFile(QOpenGLShader::Vertex, ":/new/prefix1/triangle.vert");if (!success) {qDebug() << "shaderProgram addShaderFromSourceFile failed!" << shaderProgram.log();return;}success = shaderProgram.addShaderFromSourceFile(QOpenGLShader::Fragment, ":/new/prefix1/triangle.frag");if (!success) {qDebug() << "shaderProgram addShaderFromSourceFile failed!" << shaderProgram.log();return;}success = shaderProgram.link();if(!success) {qDebug() << "shaderProgram link failed!" << shaderProgram.log();}//VAO,VBO数据部分GLfloat vertices[] = {0.7f,  0.5f, 0.0f,  // top right0.5f, -0.6f, 0.0f,  // bottom right-0.6f, -0.5f, 0.0f,  // bottom left-0.5f,  0.7f, 0.0f   // top left};unsigned int indices[] = {  // note that we start from 0!0, 1, 3,  // first Triangle1, 2, 3   // second Triangle};QOpenGLVertexArrayObject::Binder vaoBind(&vao);vbo.create();vbo.bind();vbo.allocate(vertices, sizeof(vertices));ebo.create();ebo.bind();ebo.allocate(indices, sizeof(indices));int attr = -1;attr = shaderProgram.attributeLocation("aPos");shaderProgram.setAttributeBuffer(attr, GL_FLOAT, 0, 3, sizeof(GLfloat) * 3);shaderProgram.enableAttributeArray(attr);vbo.release();
//    remember: do NOT unbind the EBO while a VAO is active as the bound element buffer object IS stored in the VAO; keep the EBO bound.
//    ebo.release();
}void QtFunctionWidget::resizeGL(int w, int h){glViewport(0, 0, w, h);
}void QtFunctionWidget::paintGL(){glClearColor(0.2f, 0.2f, 0.0f, 1.0f);glClear(GL_COLOR_BUFFER_BIT);shaderProgram.bind();{QOpenGLVertexArrayObject::Binder vaoBind(&vao);glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);}shaderProgram.release();
}

在这里插入图片描述

4、Qt + QOpenGLWindow

  • untitled4.pro
QT       += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgetsTARGET = OpenGL
TEMPLATE = app
CONFIG += c++11SOURCES += \main.cpp \mywindow.cppHEADERS += \mywindow.hLIBS += -lopengl32\-lglu32
  • main.cpp
#include <QApplication>
#include <MyWindow.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);MyWindow w;w.setWidth(640);w.setHeight(480);w.setTitle(QString::fromLocal8Bit("爱看书的小沐"));w.show();return a.exec();
}
  • mywindow.h
#ifndef WINDOW_H
#define WINDOW_H#include <QOpenGLWindow>
#include <QOpenGLFunctions>
#include <QTimer>class MyWindow : public QOpenGLWindow, protected QOpenGLFunctions
{Q_OBJECT
public:MyWindow();~MyWindow();protected:void initializeGL();          //初始化设置void resizeGL(int w, int h);  //窗口尺寸变化响应函数void paintGL();               //重绘响应函数
private:GLfloat angle;                //定义旋转角度QTimer *timer;                //定义新的定时器
};#endif // WINDOW_H
  • mywindow.cpp
#include "mywindow.h"MyWindow::MyWindow()
{timer = new QTimer();angle = 0.0;connect(timer, SIGNAL(timeout()), this, SLOT(update()));timer->start(100);
}MyWindow::~MyWindow()
{}void MyWindow::initializeGL()
{initializeOpenGLFunctions();glClearColor(0.0,0.0,0.0,0.0);glClearDepth(1.0);
}void MyWindow::resizeGL(int w, int h)
{Q_UNUSED(w);Q_UNUSED(h);
}void MyWindow::paintGL()
{glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);glLoadIdentity();glRotated(angle,0.0,1.0,0.0);glBegin(GL_TRIANGLES);glColor3f(1.0,0.0,0.0);glVertex3f(0.0,0.8,0.0);glColor3f(0.0,0.0,1.0);glVertex3f(0.5,0.0,0.0);glColor3f(0.0,1.0,0.0);glVertex3f(-0.5,0.0,0.0);glEnd();angle+=10.0;
}

程序运行如下:
在这里插入图片描述

5、Qt + glut

https://freeglut.sourceforge.net/

freeglut是OpenGL实用工具工具包(GLUT)库的免费软件/开源替代品。GLUT最初由Mark Kilgard编写,用于支持OpenGL“红皮书”第二版中的示例程序。从那时起,GLUT就被广泛应用于各种实际应用中,因为它简单、可用性广、便携性强。
GLUT(以及freeglut)负责创建窗口、初始化OpenGL上下文和处理输入事件所需的所有特定于系统的家务,以实现真正可移植的OpenGL程序。
freeglut是在X-Consortium许可下发布的。

在这里插入图片描述

  • untitled4.pro
LIBS += -L$$PWD\lib -lfreeglut
CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
INCLUDEPATH += includeSOURCES += \main.cpp
  • main.cpp
#include "GL/glut.h"void display(void)
{// clear all pixelsglClear(GL_COLOR_BUFFER_BIT);glColor3f(0.5, 0.1, 1.0);glBegin(GL_POLYGON);glVertex3f(0.20, 0.20, 0.0);glVertex3f(0.80, 0.20, 0.0);glVertex3f(0.80, 0.80, 0.0);glVertex3f(0.20, 0.80, 0.0);glEnd();glFlush();
}void init(void)
{// select clearing color: blueglClearColor(0.0, 1.0, 0.0, 0.0);// initialize viewing valuesglMatrixMode(GL_PROJECTION);glLoadIdentity();glOrtho(0.0, 1.0, 0.0, 1.0, -1.0, 1.0);
}int main(int argc, char *argv[])
{glutInit(&argc, argv);glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);glutInitWindowSize(640, 240);glutInitWindowPosition(480, 320);glutCreateWindow("爱看书的小沐");init();glutDisplayFunc(display);glutMainLoop();return 0;
}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
程序运行后:
在这里插入图片描述

6、Qt + glfw

https://www.glfw.org/

GLFW是一个开源、多平台的库,用于OpenGL、OpenGL ES和Vulkan在桌面上的开发。它提供了一个简单的API,用于创建窗口、上下文和表面,接收输入和事件。
GLFW是用C语言编写的,支持Windows、macOS、Wayland和X11。
GLFW是根据zlib/libpng许可证获得许可的。

在这里插入图片描述

  • untitled4.pro
LIBS += -L$$PWD\lib -lglfw3 -lopengl32 -lGlU32 -luser32 -lkernel32 -lgdi32CONFIG += c++11
DEFINES += QT_DEPRECATED_WARNINGS
INCLUDEPATH += includeSOURCES += \main.cpp
  • main.cpp
#include <iostream>
#include "GLFW/glfw3.h"
using namespace std;int main(int argc, char *argv[])
{GLFWwindow* window;/* Initialize the library */if (!glfwInit())return -1;/* Create a windowed mode window and its OpenGL context */window = glfwCreateWindow(640, 480, "Hello World", NULL, NULL);if (!window){glfwTerminate();return -1;}/* Make the window's context current */glfwMakeContextCurrent(window);/* Loop until the user closes the window */while (!glfwWindowShouldClose(window)){/* Render here */glClear(GL_COLOR_BUFFER_BIT);/* Swap front and back buffers */glfwSwapBuffers(window);/* Poll for and process events */glfwPollEvents();}glfwTerminate();return 0;
}

在这里插入图片描述在这里插入图片描述
程序运行如下:
在这里插入图片描述

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭
如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O???
如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡)
感谢各位童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

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

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

相关文章

计算机网络:路由协议

路由协议简介 路由协议是计算机网络中不可或缺的一部分&#xff0c;它们负责确定数据包从源地址到目的地址的最佳路径。想象一下&#xff0c;如果你是一个数据包&#xff0c;路由协议就像是地图或导航工具&#xff0c;指导你如何到达目的地。 目录 路由协议简介 工作原理简化…

解决i18n国际化可读性问题,傻瓜式webpack中文支持国际化插件开发

先来看最后的效果 问题 用过国际化i18n的朋友都知道&#xff0c;天下苦国际化久矣&#xff0c;尤其是中文为母语的开发者&#xff0c;在面对代码中一堆的$t(abc.def)这种一点也不直观毫无可读性的代码&#xff0c;根本不知道自己写了啥 &#xff08;如上图&#xff0c;你看得出…

【从零开始学习重要知识点 | 第一篇】快速了解什么是幂等性以及常见解决方案

前言&#xff1a; 当我们在设计和实现分布式系统时&#xff0c;幂等性是一个非常重要的概念。幂等性可以简单地理解为&#xff1a;对于同一操作&#xff0c;不论执行多少次&#xff0c;产生的影响都是相同的。这个概念在分布式系统中非常重要&#xff0c;因为在这种环境下&…

Adobe Premiere Pro 引入AI提升对话音质;Stable Diffusion:AI图像生成简介

&#x1f989; AI新闻 &#x1f680; Adobe Premiere Pro 引入AI提升对话音质 摘要&#xff1a;Adobe公司最近发布了一项更新&#xff0c;为其视频编辑软件Premiere Pro&#xff08;22.4版本&#xff09;新增了一个名为Enhance Speech的功能&#xff0c;通过AI技术自动调节对…

GSVA -- 学习记录

文章目录 1.原理简介2. 注意事项3. 功能实现代码实现部分 4.可视化5.与GSEA比较 1.原理简介 Gene Set Variation Analysis (GSVA) 基因集变异分析。可以简单认为是样本数据中的基因根据表达量排序后形成了一个rank list&#xff0c;这个rank list 与 预设的gene sets&#xff…

Nginx反向代理ip透传与负载均衡

前言 上篇介绍了nginx服务器单向代理和动静分离等相关内容&#xff0c;可参考Nginx重写功能和反向代理-CSDN博客&#xff0c;这里就ip透传和负载均衡对nginx反向代理做进一步了解。 目录 一、客户端ip透传 1. 概述 2. 一级代理 2.1 图示 2.2 操作过程 3. 二级代理 3.…

maven的私服

什么是maven的私服就是把自己写的工具类共享给别人这样大家都能用到你写的工具类不用重复写提示效率 maven的上传与下载示意图 1.什么是发行版本&#xff1f;发行版本指定的是功能稳定可以共大家使用的版本 2.什么是快照版本&#xff1f;快照版本指定的是指正在开发的版本 3…

Spring与SpringBoot入门

Spring入门 要使用Spring最起码需要引入两个依赖: <!-- Spring Core&#xff08;核心&#xff09; --><dependency><groupId>org.springframework</groupId><artifactId>spring-core</artifactId><version>5.3.20</version>…

PostgreSQL中int类型达到上限的一些处理方案

使用int类型作为表的主键在pg中是很常见的情况&#xff0c;但是pg中int类型的范围在-2147483648到2147483647&#xff0c;最大只有21亿&#xff0c;这个在一些大表中很容易就会达到上限。一旦达到上限&#xff0c;那么表中便没办法在插入数据了&#xff0c;这个将会是很严重的问…

网络安全之内容安全

内容安全 攻击可能只是一个点&#xff0c;防御需要全方面进行 IAE引擎 DFI和DPI技术--- 深度检测技术 DPI --- 深度包检测技术--- 主要针对完整的数据包&#xff08;数据包分片&#xff0c;分段需要重组&#xff09;&#xff0c;之后对 数据包的内容进行识别。&#xff08;应用…

Unity2023.1.19_Embedded Browser-ZFBrowser插件

Unity2023.1.19_Embedded Browser-ZFBrowser插件 官方说明文档可以仔细看一下&#xff1a; ZFBrowser Documentation (zenfulcrum.com) ZFBrowser插件的简单直接使用&#xff1a; 导入插件包资源&#xff0c;遵循常规导包原则即可&#xff1b; 抓取包文件夹下的预制体组件…

【Docker】安装及相关的命令

目录 一 Docker简介 1.1 是什么 1.2 优缺点 1.3 应用场景 1.4 安装 二 命令 2.1 Docker基本命令 2.2 Docker镜像命令 2.3 Docker容器命令 一 Docker简介 1.1 是什么 Docker是一个开源的应用容器引擎&#xff0c;它基于Go语言实现&#xff0c;并利用操作系统本身已有的…

Apache POl

介绍 Apache POl是一个处理Miscrosoft Ofice各种文件格式的开源项目。简单来说就是&#xff0c;我们可以使用 POI 在 Java 程序中对Miscrosoft Office各种文件进行读写操作,一般情况下&#xff0c;POI都是用于操作 Excel 文件。 Apache POl 的应用场景 1.银行网银系统导出交易…

禁止safari浏览器网页双击缩放功能

普通浏览器 普通浏览器&#xff0c;只需要增加meta标签禁止缩放功能就行了 <meta content"widthdevice-width, initial-scale1.0, maximum-scale1.0, user-scalable0;" name"viewport" /> user-scalableno或0 //禁止双指缩放页面initial-scale1.0…

【Java设计模式】四、适配器模式

文章目录 1、适配器模式2、举例 1、适配器模式 适配器模式Adapter Pattern&#xff0c;是做为两个不兼容的接口之间的桥梁目的是将一个类的接口转换成客户希望的另外一个接口适配器模式可以使得原本由于接口不兼容而不能一起工作的那些类可以一起工作 最后&#xff0c;适配器…

CSS3技巧37:JS+CSS3 制作旋转图片墙

开学了就好忙啊&#xff0c;Three.js 学习的进度很慢。。。 备课备课才是王道。 更一篇 JS CSS3 的内容&#xff0c;做一个图片墙。 其核心要点是把图片摆成这个样子&#xff1a; 看上去这个布局很复杂&#xff0c;其实很简单。其思路是&#xff1a; 所有图片放在一个 div.…

人工智能之Tensorflow程序结构

TensorFlow作为分布式机器学习平台&#xff0c;主要架构如下&#xff1a; 网络层&#xff1a;远程过程调用(gRPC)和远程直接数据存取(RDMA)作为网络层&#xff0c;主要负责传递神经网络算法参数。 设备层&#xff1a;CPU、GPU等设备&#xff0c;主要负责神经网络算法中具体的运…

【数据结构】OJ面试题《设计循环队列》(题库+代码)

1.前言 本题需要结构体和数组的知识&#xff0c;记录每天的刷题&#xff0c;继续坚持&#xff01; 2.OJ题目训练 设计循环队列 设计你的循环队列实现。 循环队列是一种线性数据结构&#xff0c;其操作表现基于 FIFO&#xff08;先进先出&#xff09;原则并且队尾被连接在队…

UE5 C++ 单播 多播代理 动态多播代理

一. 代理机制&#xff0c;代理也叫做委托&#xff0c;其作用就是提供一种消息机制。 发送方 &#xff0c;接收方 分别叫做 触发点和执行点。就是软件中的观察者模式的原理。 创建一个C Actor作为练习 二.单播代理 创建一个C Actor MyDeligateActor作为练习 在MyDeligateAc…

Tuning Language Models by Proxy

1、写作动机&#xff1a; 调整大语言模型已经变得越来越耗资源&#xff0c;或者在模型权重是私有的情况下是不可能的。作者引入了代理微调&#xff0c;这是一种轻量级的解码时算法&#xff0c;它在黑盒 大语言模型 之上运行&#xff0c;以达到直接微调模型的结果&#xff0c;但…