五、OpenGL中Shader与C++数据传输

文章目录

    • 一、概述
    • 二、Shader 代码文件的基本格式
    • 三、Shader的向量语法介绍
    • 四、Shader之间的数据传输
    • 五、Shader与C++的数据传输uniform
    • 六、完整示例

一、概述

在 OpenGL 中,Shader(着色器)使用 GLSL(OpenGL Shading Language) 编写,GLSL 是一种类似 C 语言的着色器编程语言。着色器的基本语法包括 版本声明、变量声明、主函数 等。

二、Shader 代码文件的基本格式

每个 Shader 代码文件的基本格式如下:

#version version_number
in type in_variable_name;
in type in_variable_name;

out type out_variable_name;

uniform type uniform_name;

void main()
{
    out_variable_name = weird_stuff_we_processed;
}

1. 版本声明

#version version_number

作用:指定 GLSL 版本号。
示例:

  • #version 330 core (OpenGL 3.3)
  • #version 450 core (OpenGL 4.5)

不同的 OpenGL 版本支持不同的 GLSL 语法特性,使用适当的版本号可以确保着色器代码正确编译。

2. 输入变量(in)

in type in_variable_name;
in type in_variable_name;

作用:定义输入变量,接收数据。
适用范围:

  • 顶点着色器(Vertex Shader):接收 CPU 传递的顶点数据(如位置、颜色、法线等)。
  • 片段着色器(Fragment Shader):接收 来自顶点着色器的插值数据。

示例(顶点着色器输入):

in vec3 aPos;    // 顶点坐标
in vec3 aColor;  // 顶点颜色

示例(片段着色器输入):

in vec3 vertexColor; // 顶点着色器传递的颜色

3. 输出变量(out)

out type out_variable_name;

作用:

  • 顶点着色器(Vertex Shader):将数据传递到片段着色器。
  • 片段着色器(Fragment Shader):输出最终的像素颜色。

示例(顶点着色器的输出):

out vec3 vertexColor;  // 传递颜色到片段着色器

示例(片段着色器的输出):

out vec4 FragColor;  // 最终的片段颜色

4. Uniform(全局变量)

uniform type uniform_name;

作用:

  • uniform 变量是全局变量,在 CPU 侧由 OpenGL 代码设置,可用于变换矩阵、光照参数、时间变量等。
  • uniform 变量的值在 所有顶点/片段之间保持一致,不会在不同的顶点或片段间变化。

示例(用于变换矩阵):

uniform mat4 model;       // 模型变换矩阵
uniform mat4 view;        // 视图变换矩阵
uniform mat4 projection;  // 投影变换矩阵

示例(用于纹理):

uniform sampler2D texture1;  // 纹理

5. main() 主函数

void main()
{
    out_variable_name = weird_stuff_we_processed;
}

作用:

  • main() 函数是 GLSL 的入口点,每个 顶点(顶点着色器)或 像素(片段着色器)都会执行一次。
  • out_variable_name = weird_stuff_we_processed; 表示计算并输出结果。

完整示例
(1)顶点着色器

#version 330 core

layout(location = 0) in vec3 aPos;    // 顶点坐标
layout(location = 1) in vec3 aColor;  // 顶点颜色

out vec3 vertexColor; // 传递给片段着色器的颜色

uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;

void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
    vertexColor = aColor;  // 传递颜色
}

解析:

  • in 变量 aPos:接收 CPU 传来的顶点坐标数据。
  • in 变量 aColor:接收 CPU 传来的顶点颜色数据。
  • out 变量 vertexColor:将颜色传递到片段着色器。
  • uniform 变量 model, view, projection:用于变换矩阵,调整顶点位置。

(2) 片段着色器

#version 330 core

in vec3 vertexColor; // 从顶点着色器接收的颜色
out vec4 FragColor;  // 最终颜色输出

void main()
{
    FragColor = vec4(vertexColor, 1.0);
}

解析:

  • in 变量 vertexColor:接收 顶点着色器传递的颜色。
  • out 变量 FragColor:输出最终的片段颜色。

总结:
在这里插入图片描述

三、Shader的向量语法介绍

在 GLSL(OpenGL Shading Language)中,向量(Vector)是图形渲染中最常用的数据类型之一,主要用于存储坐标、颜色、法线、纹理坐标等信息。GLSL 提供了vec2、vec3、vec4 这三种向量类型,以及多种操作方式。

1. 向量类型
GLSL 主要支持以下浮点型向量:
在这里插入图片描述
此外,还有整型和布尔型向量:
在这里插入图片描述
2. 向量初始化
GLSL 支持多种方式初始化向量:

(1) 直接赋值

vec2 a = vec2(1.0, 2.0);
vec3 b = vec3(0.5, 0.2, 0.7);
vec4 c = vec4(1.0, 0.0, 0.5, 1.0);

(2) 复制构造

vec3 v1 = vec3(0.5);   // v1 = (0.5, 0.5, 0.5)
vec4 v2 = vec4(v1, 1.0); // v2 = (0.5, 0.5, 0.5, 1.0)

(3) 通过其它向量构造

vec2 v = vec2(0.3, 0.6);
vec4 newVec = vec4(v, 1.0, 0.0);  // newVec = (0.3, 0.6, 1.0, 0.0)

3. 向量分量访问(Swizzling)
GLSL 允许使用 .x, .y, .z, .w 访问或重新排列向量的分量,类似于 struct 的成员访问。

(1) 访问单个分量

vec4 color = vec4(0.2, 0.5, 0.7, 1.0);
float red = color.x;   // red = 0.2
float alpha = color.w; // alpha = 1.0

(2) 访问多个分量(Swizzling)

vec4 pos = vec4(1.0, 2.0, 3.0, 4.0);
vec2 v2 = pos.xy;   // v2 = (1.0, 2.0)
vec3 v3 = pos.zyx;  // v3 = (3.0, 2.0, 1.0)
vec4 v4 = pos.xxyy; // v4 = (1.0, 1.0, 2.0, 2.0)

(3) 组合不同分量

vec3 color = vec3(1.0, 0.5, 0.3);
vec4 newColor = vec4(color.yxz, 1.0);  // newColor = (0.5, 1.0, 0.3, 1.0)

4. 向量运算
GLSL 允许对向量进行各种运算,如加法、减法、乘法、除法、点积、叉积等。

(1) 逐元素加法、减法

vec3 a = vec3(1.0, 2.0, 3.0);
vec3 b = vec3(0.5, 0.2, 0.7);
vec3 sum = a + b;  // (1.5, 2.2, 3.7)
vec3 diff = a - b; // (0.5, 1.8, 2.3)

(2) 逐元素乘法、除法

vec3 c = vec3(2.0, 3.0, 4.0);
vec3 d = c * 2.0;  // (4.0, 6.0, 8.0) - 每个分量都乘以 2
vec3 e = c / 2.0;  // (1.0, 1.5, 2.0) - 每个分量都除以 2

(3) 点积(Dot Product)

float dotProduct = dot(vec3(1.0, 2.0, 3.0), vec3(4.0, 5.0, 6.0));  
// dotProduct = (1*4 + 2*5 + 3*6) = 32

作用:计算两个向量的相似程度,常用于光照计算。

(4) 叉积(Cross Product)

vec3 crossProduct = cross(vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0));
// crossProduct = (0.0, 0.0, 1.0)

作用:计算垂直于两个向量的法向量,用于法线计算。

5. 常用数学函数
GLSL 提供了一些常见的数学函数来处理向量。

(1) 向量长度

float len = length(vec3(3.0, 4.0, 0.0));  // len = 5.0

(2) 归一化(Normalization)

vec3 normVec = normalize(vec3(3.0, 4.0, 0.0));  
// normVec = (0.6, 0.8, 0.0)

作用:将向量变为单位向量,方向不变,但长度为 1。

(3) 线性插值(Lerp)

vec3 lerpVec = mix(vec3(1.0, 0.0, 0.0), vec3(0.0, 0.0, 1.0), 0.5);
// lerpVec = (0.5, 0.0, 0.5)

作用:在两个向量之间进行插值,mix(a, b, t) 计算 a * (1-t) + b * t。

总结:
在这里插入图片描述

四、Shader之间的数据传输

1. 顶点着色器 (Vertex Shader)

#version 330 core
layout (location = 0) in vec3 aPos; // 顶点位置,attribute 变量

out vec4 vertexColor; // 输出到片段着色器的颜色数据

void main()
{
    gl_Position = vec4(aPos, 1.0); // 将 vec3 转换为 vec4,赋值给 OpenGL 的 gl_Position
    vertexColor = vec4(0.5, 0.0, 0.0, 1.0); // 设置颜色,深红色
}

输入 (Input):

  • layout (location = 0) in vec3 aPos;
  • aPos 是从 OpenGL 的 VBO (Vertex Buffer Object) 传入的顶点位置数据。
  • layout(location = 0) 绑定顶点数据到 attribute 位置 0。

处理 (Processing)

  • gl_Position = vec4(aPos, 1.0);
  • gl_Position 是固定的 OpenGL 变量,用于存储变换后的顶点坐标,最终传递给光栅化阶段。
  • aPos 是 vec3,而 gl_Position 需要 vec4,所以用 vec4(aPos, 1.0) 进行转换。

输出 (Output)

  • out vec4 vertexColor;
  • vertexColor 是一个 out 变量,它存储颜色信息,并传递给片段着色器。
  • vertexColor = vec4(0.5, 0.0, 0.0, 1.0);比如颜色值 (0.5, 0.0, 0.0, 1.0),代表深红色 (Dark Red)。
  • 这个颜色会插值传递给片段着色器。

2. 片段着色器 (Fragment Shader)

#version 330 core
out vec4 FragColor; // 输出最终颜色

in vec4 vertexColor; // 从顶点着色器传入的颜色数据

void main()
{
    FragColor = vertexColor; // 直接使用插值后的 vertexColor
}

输入 (Input)

  • in vec4 vertexColor;
  • 这个变量与顶点着色器中的 out vec4 vertexColor对应,用于接收插值后的颜色数据。

处理 (Processing)
这里没有额外的计算,直接使用 vertexColor。

输出 (Output)

  • out vec4 FragColor;
  • FragColor 是最终的片段颜色,输出到屏幕。

3. 顶点着色器与片段着色器的连接
顶点着色器的 out vec4 vertexColor变量自动插值后传递给片段着色器的 in vec4 vertexColor;
插值 (Interpolation) 机制:

  • 顶点着色器的 vertexColor 值会在片元之间进行线性插值。
  • 如果顶点着色器的颜色是 (0.5, 0.0, 0.0, 1.0),则片段着色器接收到的颜色会根据顶点插值。

4. 传输流程总结

VBO (aPos) → 顶点着色器 (gl_Position, vertexColor) → 片段着色器 (vertexColor → FragColor) → 颜色缓冲区

五、Shader与C++的数据传输uniform

在 OpenGL 中,uniform 变量用于在 C++ 代码和 Shader 之间传递数据。与 in/out 不同,uniform 是全局变量,在着色器的所有 invocations(调用)中都保持相同的值。

1. uniform 在 GLSL (Shader) 中的使用
在 GLSL 着色器中,我们可以声明 uniform 变量,例如:

#version 330 core

uniform mat4 model; // 4x4 模型矩阵
uniform mat4 view;  // 4x4 视图矩阵
uniform mat4 projection; // 4x4 投影矩阵

in vec3 aPos; // 顶点位置
void main()
{
    gl_Position = projection * view * model * vec4(aPos, 1.0);
}

解析:

  • uniform mat4 model; → 模型变换矩阵(物体自身的变换)
  • uniform mat4 view; → 视图变换矩阵(摄像机的变换)
  • uniform mat4 projection; → 投影变换矩阵(投影方式)
  • gl_Position = projection * view * model * vec4(aPos, 1.0);最终计算出的顶点位置,经过 3D 变换后传入 OpenGL 渲染管线。

2. 在 C++ 中传递 uniform 数据
在 OpenGL 的 C++ 代码中,我们需要:

  • 获取 uniform 变量的 location
  • 传递数据给 uniform

步骤 1:获取 uniform 变量的位置
在 C++ 中,我们可以使用 glGetUniformLocation 获取着色器中 uniform 变量的位置:

GLuint shaderProgram = ...; // 已编译和链接的 Shader 程序
GLint modelLoc = glGetUniformLocation(shaderProgram, "model");
GLint viewLoc = glGetUniformLocation(shaderProgram, "view");
GLint projectionLoc = glGetUniformLocation(shaderProgram, "projection");

例如:glGetUniformLocation(shaderProgram, “model”);获取 model 变量在 Shader 中的地址,如果 model 变量不存在或者优化掉了,会返回 -1。

步骤 2:传递数据给 uniform
(1)传递 4x4 矩阵

glm::mat4 model = glm::mat4(1.0f);  // 单位矩阵
glm::mat4 view = glm::lookAt(glm::vec3(0.0f, 0.0f, 3.0f), glm::vec3(0.0f, 0.0f, 0.0f), glm::vec3(0.0f, 1.0f, 0.0f));
glm::mat4 projection = glm::perspective(glm::radians(45.0f), 800.0f / 600.0f, 0.1f, 100.0f);

// 传递矩阵数据
glUniformMatrix4fv(modelLoc, 1, GL_FALSE, glm::value_ptr(model));
glUniformMatrix4fv(viewLoc, 1, GL_FALSE, glm::value_ptr(view));
glUniformMatrix4fv(projectionLoc, 1, GL_FALSE, glm::value_ptr(projection));

解析:
glUniformMatrix4fv(location, count, transpose, value)

  • location → glGetUniformLocation() 获取的 uniform 变量地址
  • count → 传递的矩阵个数(一般是 1)
  • transpose → 是否需要转置(一般为 GL_FALSE,OpenGL 期望列优先存储)
  • value → 指向矩阵数据的指针(glm::value_ptr(matrix))

(2)传递 float 类型的 uniform
Shader 代码:

uniform float time; // 时间变量

C++ 代码:

GLint timeLoc = glGetUniformLocation(shaderProgram, "time");
float currentTime = glfwGetTime();
glUniform1f(timeLoc, currentTime);

(3)传递 vec3(三维向量)
Shader 代码:

uniform vec3 lightColor;

C++ 代码:

GLint lightColorLoc = glGetUniformLocation(shaderProgram, "lightColor");
glUniform3f(lightColorLoc, 1.0f, 1.0f, 1.0f); // 传递白色光

或者使用 glm::vec3:

glm::vec3 lightColor = glm::vec3(1.0f, 1.0f, 1.0f);
glUniform3fv(lightColorLoc, 1, glm::value_ptr(lightColor));

(4)传递 bool 和 int
Shader 代码:

uniform bool useTexture;
uniform int lightMode;

C++ 代码:

GLint useTextureLoc = glGetUniformLocation(shaderProgram, "useTexture");
GLint lightModeLoc = glGetUniformLocation(shaderProgram, "lightMode");

// 传递 bool(OpenGL 没有 glUniform1b,所以用 int 代替)
glUniform1i(useTextureLoc, true);

// 传递 int
glUniform1i(lightModeLoc, 2);

(5)总结
在这里插入图片描述

六、完整示例

vertex_shader.vert

#version 330 core
layout (location = 0) in vec3 aPos;

void main()
{
    gl_Position = vec4(aPos, 1.0);
}

fragment_shader.frag

#version 330 core
out vec4 FragColor;
uniform vec4 ourColor;

void main()
{
    FragColor = ourColor;
}

代码如下:

#include <iostream>
#include <string>
#include <fstream>
#include <sstream>
#include "glad/glad.h"
#include "GLFW/glfw3.h"

GLuint VBO = 0;
GLuint VAO = 0;
GLuint shaderProgram = 0;

void framebuffer_size_callback(GLFWwindow* window, int width, int height) {
	glViewport(0, 0, width, height);
}

void processInput(GLFWwindow* window) {
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS) {
		glfwSetWindowShouldClose(window, true);
	}
}

void rend() {
	glUseProgram(shaderProgram); //需要先调用才能生效

	float _time = glfwGetTime();
	float _green = sin(_time) * 0.5f + 0.5f;
	int _location = glGetUniformLocation(shaderProgram, "ourColor");
	glUniform4f(_location, 0.0f, _green, 0.0f, 1.0f);

	glBindVertexArray(VAO);
	glDrawArrays(GL_TRIANGLES, 0, 3);
	glBindVertexArray(0);
	glUseProgram(0);
}

void initModel() {
	float vertices[] = {
		-0.5f, -0.5f, 0.0f,
		0.5f, -0.5f, 0.0f,
		0.0f, 0.5f, 0.0f
	};

	glGenVertexArrays(1, &VAO);
	glBindVertexArray(VAO);

	glGenBuffers(1, &VBO); //获取vbo的index
	glBindBuffer(GL_ARRAY_BUFFER, VBO); //绑定vbo的index,给vbo分配显存空间,传输数据
	//告诉shader数据解析格式
	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);
}

void initShader(const char* _vertexPath, const char* _fragmPath) {
	std::string _vertexCode("");
	std::string _fragCode("");

	std::ifstream _vShaderFile;
	std::ifstream _fShaderFile;

	_vShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
	_fShaderFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);

	try {
		_vShaderFile.open(_vertexPath);
		_fShaderFile.open(_fragmPath);

		std::stringstream _vShaderStream, _fShaderStream;
		_vShaderStream << _vShaderFile.rdbuf();
		_fShaderStream << _fShaderFile.rdbuf();

		_vertexCode = _vShaderStream.str();
		_fragCode = _fShaderStream.str();
	} catch (const std::exception&) {
		std::string errStr = "read shader fail";
		std::cout << errStr << std::endl;
	}

	const char* _vShaderStr = _vertexCode.c_str();
	const char* _fShaderStr = _fragCode.c_str();

	//shader的编译链接
	unsigned int _vertexID = 0, _fragID = 0;
	char _inforLog[512] = { 0 };
	int _successFlag = 0;

	
	//编译
	_vertexID = glCreateShader(GL_VERTEX_SHADER);
	glShaderSource(_vertexID, 1, &_vShaderStr, NULL);
	glCompileShader(_vertexID);

	glGetShaderiv(_vertexID, GL_COMPILE_STATUS, &_successFlag);
	if (_successFlag) {
		glGetShaderInfoLog(_vertexID, 512, NULL, _inforLog);
		std::string errstr(_inforLog);
		std::cout << _inforLog << std::endl;
	}

	_fragID = glCreateShader(GL_FRAGMENT_SHADER);
	glShaderSource(_fragID, 1, &_fShaderStr, NULL);
	glCompileShader(_fragID);

	glGetShaderiv(_fragID, GL_COMPILE_STATUS, &_successFlag);
	if (_successFlag) {
		glGetShaderInfoLog(_vertexID, 512, NULL, _inforLog);
		std::string errstr(_inforLog);
		std::cout << _inforLog << std::endl;
	}

	//链接
	shaderProgram = glCreateProgram();
	glAttachShader(shaderProgram, _vertexID);
	glAttachShader(shaderProgram, _fragID);
	glLinkProgram(shaderProgram);

	glGetProgramiv(shaderProgram, GL_LINK_STATUS, &_successFlag);
	if (!_successFlag) {
		glGetProgramInfoLog(shaderProgram, 512, NULL, _inforLog);
		std::string errStr(_inforLog);
		std::cout << _inforLog << std::endl;
	}
	glDeleteShader(_vertexID);
	glDeleteShader(_fragID);
}

int main() {
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

	GLFWwindow* window = glfwCreateWindow(800, 600, "OPenGL Core", NULL, NULL);
	if (window == NULL) {
		std::cout << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}
	glfwMakeContextCurrent(window);

	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
		std::cout << "Failed to initialize GLAD" << std::endl;
		return -1;
	}

	glViewport(0, 0, 800, 600);
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

	initModel();
	initShader("vertex_shader.vert", "fragment_shader.frag");

	while (!glfwWindowShouldClose(window)) {
		processInput(window);

		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);

		rend();

		glfwSwapBuffers(window);
		glfwPollEvents();
	}

	// 删除 VAO 和 VBO
	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1, &VBO);

	// 清理
	glfwTerminate();
	
	return 0;
}

输出结果如下所示:
在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

docker不停机部署

背景 最近做大疆项目时&#xff0c;后台更新部署时&#xff0c;机场和无人机就会掉线。设备自动重连注册时间比较长&#xff0c;应用长时间不可用。所以需要灰色发布服务。docker-compose的swarm模式可解决此问题。 服务构建脚本Dockerfile # 使用官方Java基础镜像&#xff…

工作记录 2016-12-22

工作记录 2016-12-22 更新的问题 1、修改了Job Summary的Bill Amount的Bug。 2、修改了Account #的宽度。 3、修改了Clearinghouse Status的默认查询的条件。 4、修改了Upload Files的Add File的bug。 5、Pending Pool、Missing Infos加了Write Off&#xff0c;修改了Histor…

QLoggingCategory类使用

QLoggingCategory类使用 QLoggingCategory的概述 QLoggingCategory是Qt的日志策略类&#xff1b;可以通过声明不同的日志策略对象来输出不同的日志信息。打印信息类型如下&#xff1a;宏 Q_DECLARE_LOGGING_CATEGORY(name) 定义一个返回QLoggingCategory对象函数&#xff0c;…

Linux红帽:RHCSA认证知识讲解(五)从红帽和 DNF 软件仓库下载、安装、更新和管理软件包

Linux红帽&#xff1a;RHCSA认证知识讲解&#xff08;五&#xff09;从红帽和 DNF 软件仓库下载、安装、更新和管理软件包 前言一、DNF 软件包管理基础1.1 核心操作命令安装软件包卸载软件包重新安装软件包 1.2 软件仓库原理 二、配置自定义软件仓库步骤 1&#xff1a;清理默认…

Go本地缓存设计与实现

本地缓存是一个项目中很常见的组件。在很多人的眼中就是一个简单的key-value的map存储即可实现&#xff0c;但实际上&#xff0c;设计一个本地缓存需要考虑的问题远比你想象的多&#xff0c;比如说&#xff0c;本地缓存是将数据存储在内存&#xff0c;若数据量激增突破了内存限…

通义万相2.1开源版本地化部署攻略,生成视频再填利器

2025 年 2 月 25 日晚上 11&#xff1a;00 通义万相 2.1 开源发布&#xff0c;前两周太忙没空搞它&#xff0c;这个周末&#xff0c;也来本地化部署一个&#xff0c;体验生成效果如何&#xff0c;总的来说&#xff0c;它在国内文生视频、图生视频的行列处于领先位置&#xff0c…

Jetson Xavier NX安装CUDA加速的OpenCV

我们使用SDKManager刷机完成后&#xff0c;使用jtop查看&#xff0c;发现OpenCV 是不带CUDA加速的&#xff0c;因此&#xff0c;我们需要安装CUDA加速的OpenCV&#xff0c;这样后续在使用的时候速度会快很多。 首先我们先卸载默认OpenCV sudo apt purge libopencv* -y sudo …

基于PaddleNLP使用DeepSeek-R1搭建智能体

基于PaddleNLP使用DeepSeek-R1搭建智能体 最近在学习DeepSeek&#xff0c;找到了PaddleNLP星河社区大模型&#xff0c;跟着敲写了一遍。内容来源&#xff1a;DeepSeek实战训练营&#xff1a;从云端模型部署到应用开发 - 飞桨AI Studio星河社区-人工智能学习与实训社区 本项目基…

给大家推荐8个好玩有趣的网站

1、Home Apothecary 家庭药房 https://apothecary.tips/zh Home Apothecary&#xff08;家庭药房&#xff09;结合传统中医智慧与现代科学验证&#xff0c;提供涵盖睡眠改善、免疫力提升、肠胃调理、活力增强等健康需求的天然养生饮品配方。精选安神助眠、四季调养、舒缓压力…

使用Beanshell前置处理器对Jmeter的请求body进行加密

这里我们用HmacSHA256来进行加密举例&#xff1a; 步骤&#xff1a; 1.先获取请求参数并对请求参数进行处理&#xff08;处理成String类型&#xff09; //处理请求参数的两种方法&#xff1a; //方法一&#xff1a; //获取请求 Arguments args sampler.getArguments(); //转…

利用paddleocr解决图片旋转问题

由于之前使用easyocr识别图片的时候发现旋转的图片或者倒置的图片效果很差&#xff0c;来利用 cv2.minAreaRect()获取旋转角度&#xff0c;只能解决0-90&#xff0c;对于倒置的图片不能很好解决&#xff0c;因此使用paddleocr中方向分类检测&#xff08;只能返回0&#xff0c;1…

数据结构(蓝桥杯常考点)

数据结构 前言&#xff1a;这个是针对于蓝桥杯竞赛常考的数据结构内容&#xff0c;基础算法比如高精度这些会在下期给大家总结 数据结构 竞赛中&#xff0c;时间复杂度不能超过10的7次方&#xff08;1秒&#xff09;到10的8次方&#xff08;2秒&#xff09; 空间限制&#x…

Python 入

Python 入侵交换机 随着网络安全威胁不断增加&#xff0c;对于网络设备的安全防护变得愈发重要。而交换机作为网络中重要的设备之一&#xff0c;也需要加强安全保护。本文将介绍如何利用Python来入侵交换机&#xff0c;并对其进行漏洞扫描和安全检测。 1. Python 入侵交换机原…

自然语言处理:最大期望值算法

介绍 大家好&#xff0c;博主又来给大家分享知识了&#xff0c;今天给大家分享的内容是自然语言处理中的最大期望值算法。那么什么是最大期望值算法呢&#xff1f; 最大期望值算法&#xff0c;英文简称为EM算法&#xff0c;它的核心思想非常巧妙。它把求解模型参数的过程分成…

RAG 常见分块策略全解析:从原理到代码实践(2025 深度版)

大家好,我是大 F,深耕AI算法十余年,互联网大厂技术岗。 知行合一,不写水文,喜欢可关注,分享AI算法干货、技术心得。 更多文章可关注《大模型理论和实战》、《DeepSeek技术解析和实战》,一起探索技术的无限可能! 引言 在检索增强生成(RAG)系统中,分块策略是决定系统…

【软件逆向】QQ 连连看小游戏去广告与一键消除实现

目录 一、背景介绍 二、去广告实现 2.1 分析广告加载流程 2.2 逆向分析广告加载逻辑 2.3 去广告方案 三、一键消除外挂实现 3.1 分析游戏逻辑 3.2 编写外挂插件 3.3 注入外挂&#xff1a; 四、一键消除效果展示 五、额外扩展 一、背景介绍 QQ 连连看是一款经典的休闲…

小白学Agent技术[5](Agent框架)

文章目录 Agent框架Single Agent框架BabyAGIAutoGPTHuggingGPTHuggingGPT工作原理说明GPT-EngineerAppAgentOS-Copilot Multi-Agent框架斯坦福虚拟小镇TaskWeaverMetaGPT微软UFOAgentScope现状 常见Agent项目比较概述技术规格和能力实际应用案例开发体验比较ChatChain模式 Agen…

AI写论文提示词指令大全,快速写论文

目录 一、十大学术写作提示词1、研究主题2、研究问题3、论文架构4、学术论证5、文献关键要素6、专业文本可读性转换7、学术语言规范化8、提高语言准确性9、多维度、深层论证10、优化文本结构 二、快速写论文提示词1、确认研究选题2、整理相关资料3、快速完成论文大纲4、整合文献…

电子电气架构 ---常见车规MCU安全启动方案

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…

HCIP第二讲作业

一、连接拓扑图 二、配置要求 1.学校内部的HTTP客户端可以正常通过域名www.baidu.com访问到百度网络中的HTTP服务器 2.学校网络内部网段基于192.168.1.0/24划分&#xff0c;PC1可以正常访问3.3.3.0/24网段&#xff0c;但是PC2不允许 3.学校内部路由使用静态路由&#xff0c;R1…