OpenGL_Learn07(变换)

1.  向量

向量有一个方向和一个大小。如果一个向量有2个维度,它表示一个平面的方向(想象一下2D的图像),当它有3个维度的时候它可以表达一个3D世界的方向。

可以把这些2D向量当做z坐标为0的3D向量。

2. 向量内积和外积

向量的点乘(内积):简单来说就是可以判断向量方向的相似性

向量外积:简单来说就是可以得到其法向量

3. 向量的加减和长度

向量的加法可以被定义为是分量的(Component-wise)相加,即将一个向量中的每一个分量加上另一个向量的对应分量。

v = (4, 2)k = (1, 2)相加得到(4+1,2+2)

向量的减法等于加上第二个向量的相反向量。两个向量的相减会得到这两个向量指向位置的差。

我们使用勾股定理(Pythagoras Theorem)来获取向量的长度(Length)/大小(Magnitude)。如果你把向量的x与y分量画出来,该向量会和x与y分量为边形成一个三角形。

4. 旋转

5. 代码实现旋转和缩放

texture.vs

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

out vec2 TexCoord;

uniform mat4 transform;
void main()
{
    gl_Position = transform * vec4(aPos, 1.0);
    TexCoord=vec2(aTexCorrd.x,1.0-aTexCorrd.y);
}

texture.fs

#version 330 core
out vec4 FragColor;

in vec3 ourColor;
in vec2 TexCoord;

uniform float mixValue;

//texture sampler
uniform sampler2D textureone;
uniform sampler2D texturetwo;

void main()
{
    FragColor = mix(texture(textureone,TexCoord),texture(texturetwo,TexCoord),mixValue);
}

shader.h

#pragma once

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


class Shader {
public:
	//程序ID
	unsigned int ID;
	
	//构造器读取并构建着色器
	Shader(const char* vertexPath, const char* fagmentPath) {
		std::string vertexCode;
		std::string fragmentCode;
		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(fagmentPath);
			std::stringstream vShaderStream, fShaderStream;
			vShaderStream << vShaderFile.rdbuf();
			fShaderStream << fShaderFile.rdbuf();
			vShaderFile.close();
			fShaderFile.close();
			vertexCode = vShaderStream.str();
			fragmentCode = fShaderStream.str();
		}
		catch (std::ifstream::failure& e) {
			std::cout << "ERROR::SHADER::FILE_NOT_SUCCESSFULLY_READ: " << e.what() << std::endl;
		}
		const char* vShaderCode = vertexCode.c_str();
		const char* fShaderCode = fragmentCode.c_str();

		//2.complie shaders
		unsigned int vertex, fragment;
		//vertex shader
		vertex = glCreateShader(GL_VERTEX_SHADER);
		glShaderSource(vertex, 1, &vShaderCode, NULL);
		glCompileShader(vertex);
		checkCompileErros(vertex, "VERTEX");
		//fragment Shader
		fragment = glCreateShader(GL_FRAGMENT_SHADER);
		glShaderSource(fragment, 1, &fShaderCode, NULL);
		glCompileShader(fragment);
		checkCompileErros(fragment, "FRAGMENT");
		//shader Program
		ID = glCreateProgram();
		glAttachShader(ID, vertex);
		glAttachShader(ID, fragment);
		glLinkProgram(ID);
		checkCompileErros(ID, "PROGAM");

		glDeleteShader(vertex);
		glDeleteShader(fragment);


	}
	//使用/激活程序
	void use() {
		glUseProgram(ID);
	}
	//uniform工具函数
	void setBool(const std::string& name, bool value) const {
		glUniform1i(glGetUniformLocation(ID, name.c_str()), (int)value);
	}
	void setInt(const std::string& name, int value) const {
		glUniform1i(glGetUniformLocation(ID, name.c_str()), value);
	}
	void setFloat(const std::string& name, float value) const {
		glUniform1f(glGetUniformLocation(ID, name.c_str()), value);
	}


private:
	void checkCompileErros(unsigned int shader, std::string type) {
		int success;
		char infoLog[1024];
		if (type != "PROGRAM") {
			glGetShaderiv(shader, GL_COMPILE_STATUS, &success);
			if (!success) {
				glGetShaderInfoLog(shader, 1024, NULL, infoLog);
				std::cout << "ERROR::SHADER_COMPILATION_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
			}
		}
		else
		{
			glGetProgramiv(shader, GL_LINK_STATUS, &success);
			if (!success)
			{
				glGetProgramInfoLog(shader, 1024, NULL, infoLog);
				std::cout << "ERROR::PROGRAM_LINKING_ERROR of type: " << type << "\n" << infoLog << "\n -- --------------------------------------------------- -- " << std::endl;
			}
		}
	}
};

 

main.cpp

下载glm

Tags · g-truc/glm (github.com)

#include <glad/glad.h>
#include <GLFW/glfw3.h>

#include <iostream>
#include "stb_image.h"
#include <cmath>
#include "shader.h"

#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>
void framebuffer_size_callback(GLFWwindow* window, int width, int height);
void processInput(GLFWwindow* window);

// settings
const unsigned int SCR_WIDTH = 800;
const unsigned int SCR_HEIGHT = 600;

float mixValue = 0.2f;

int main() {

	//1.初始化配置
	glfwInit();
	glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);
	glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
	glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);

#ifdef __APPLE__
	glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GLFW_TRUE);
#endif // __APPLE__

	//2.gltf 窗口创建
	GLFWwindow* window = glfwCreateWindow(SCR_WIDTH, SCR_HEIGHT, "LeranOpenGL", NULL, NULL);
	if (window == NULL) {
		std::cout << "Failed to create GLFW window" << std::endl;
		glfwTerminate();
		return -1;
	}

	glfwMakeContextCurrent(window);
	glfwSetFramebufferSizeCallback(window, framebuffer_size_callback);

	//3. 加载所有GL函数指针
	if (!gladLoadGLLoader((GLADloadproc)glfwGetProcAddress)) {
		std::cout << "Failed to initialize GLAD" << std::endl;
		return -1;
	}

	Shader ourShader("./texture.vs", "./texture.fs");

	//4. 设置顶点数据
	float vertices[] = {
		// positions          // colors           // texture coords
		 0.5f,  0.5f, 0.0f, 1.0f, 1.0f, // top right
		 0.5f, -0.5f, 0.0f, 1.0f, 0.0f, // bottom right
		-0.5f, -0.5f, 0.0f, 0.0f, 0.0f, // bottom left
		-0.5f,  0.5f, 0.0f, 0.0f, 1.0f  // top left 
	};

	unsigned int indices[] = {
	0, 1, 3, // first triangle
	1, 2, 3  // second triangle
	};

	unsigned int VBO, VAO, EBO;
	glGenVertexArrays(1, &VAO);
	glGenBuffers(1, &VBO);
	glGenBuffers(1,&EBO);//元素缓冲对象:Element Buffer Object,EBO 

	glBindVertexArray(VAO);
	
	//复制顶点数组到缓冲区中供opengl使用
	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, 5 * sizeof(float), (void*)0);
	glEnableVertexAttribArray(0);
	//设置纹理属性指针
	glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 5 * sizeof(float), (void*)(3 * sizeof(float)));
	glEnableVertexAttribArray(1);

	//加载和创建纹理
	unsigned int textureone,texturetwo;
	glGenTextures(1, &textureone);
	glBindTexture(GL_TEXTURE_2D, textureone);
	//设置纹理环绕参数
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	//设置纹理过滤参数
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	//加载图像和生成mipmaps
	int width, height, nrChannels;
	stbi_set_flip_vertically_on_load(true);
	std::string filePath = R"(D:\CPlusProject\LearnOpenGL\DataSet\container.jpg)";
	unsigned char* data = stbi_load(filePath.c_str(), &width, &height, &nrChannels, 0);

	if (data) {
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, data);
		glGenerateMipmap(GL_TEXTURE_2D);
	}
	else {
		std::cout << "Failed to load texture" << std::endl;
	}

	stbi_image_free(data);


	glGenTextures(1, &texturetwo);
	glBindTexture(GL_TEXTURE_2D, texturetwo);
	//设置纹理环绕参数
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
	//设置纹理过滤参数
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);

	//加载图像和生成mipmaps
	filePath = R"(D:\CPlusProject\LearnOpenGL\DataSet\awesomeface.png)";
	unsigned char* data2 = stbi_load(filePath.c_str(), &width, &height, &nrChannels, 0);

	if (data2) {
		glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data2);
		glGenerateMipmap(GL_TEXTURE_2D);
	}
	else {
		std::cout << "Failed to load texture" << std::endl;
	}

	stbi_image_free(data2);


	
	ourShader.use();
	glUniform1i(glGetUniformLocation(ourShader.ID, "textureone"), 0);//二选一
	ourShader.setInt("texturetwo", 1);//二选一


	//glm::vec4 vec(1.0f, 0.0f, 0.0f, 1.0f);
	 译注:下面就是矩阵初始化的一个例子,如果使用的是0.9.9及以上版本
	//glm::mat4 trans = glm::mat4(1.0f);
	//trans = glm::translate(trans, glm::vec3(1.0f, 1.0f, 0.0f));
	//vec = trans * vec;
	//std::cout << vec.x << vec.y << vec.z << std::endl;

	glm::mat4 trans = glm::mat4(1.0f);
	trans = glm::rotate(trans, glm::radians(90.f), glm::vec3(0.0, 0.0, 1.0));
	trans = glm::scale(trans, glm::vec3(0.5, 0.5, 0.5));
	unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");
	glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));

	//5. 循环渲染
	while (!glfwWindowShouldClose(window)) {
		processInput(window);

		// render
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		//绑定纹理
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, textureone);
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, texturetwo);


		ourShader.setFloat("mixValue", mixValue);


		ourShader.use();
		glBindVertexArray(VAO);
		glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);

		glfwSwapBuffers(window);
		glfwPollEvents();

	}

	glDeleteVertexArrays(1, &VAO);
	glDeleteBuffers(1, &VBO);
	glDeleteBuffers(1, &EBO);

	glfwTerminate();
	return 0;

}

// process all input: query GLFW whether relevant keys are pressed/released this frame and react accordingly
// ---------------------------------------------------------------------------------------------------------
void processInput(GLFWwindow* window)
{
	if (glfwGetKey(window, GLFW_KEY_ESCAPE) == GLFW_PRESS)
		glfwSetWindowShouldClose(window, true);

	if (glfwGetKey(window, GLFW_KEY_UP) == GLFW_PRESS) {
		std::cout << "up" << std::endl;
		mixValue += 0.001f;
		if (mixValue >= 1.0f) {
			mixValue = 1.0f;
		}
	}

	if (glfwGetKey(window, GLFW_KEY_DOWN) == GLFW_PRESS)
	{
		std::cout << "down" << std::endl;
		mixValue -= 0.001f; // change this value accordingly (might be too slow or too fast based on system hardware)
		if (mixValue <= 0.0f)
			mixValue = 0.0f;
	}
	std::cout << "mixValue:" << mixValue <<std::endl;
}

// glfw: whenever the window size changed (by OS or user resize) this callback function executes
// ---------------------------------------------------------------------------------------------
void framebuffer_size_callback(GLFWwindow* window, int width, int height)
{
	// make sure the viewport matches the new window dimensions; note that width and 
	// height will be significantly larger than specified on retina displays.
	glViewport(0, 0, width, height);
}

6. 持续旋转

要让箱子随着时间推移旋转,我们必须在游戏循环中更新变换矩阵。也就是在while结构体中。

在这里我们先把箱子围绕原点(0, 0, 0)旋转,之后,我们把旋转过后的箱子位移到屏幕的右下角。

	//5. 循环渲染
	while (!glfwWindowShouldClose(window)) {
		processInput(window);

		// render
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		//绑定纹理
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, textureone);
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, texturetwo);


		ourShader.setFloat("mixValue", mixValue);

		glm::mat4 trans = glm::mat4(1.0f);
		trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
		trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));
		unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");
		glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));


		ourShader.use();
		glBindVertexArray(VAO);
		glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);

		glfwSwapBuffers(window);
		glfwPollEvents();

	}

7. 先平移后旋转And先旋转后平移

上面的例子是先平移后旋转,下面的代码是先旋转后平移

	//5. 循环渲染
	while (!glfwWindowShouldClose(window)) {
		processInput(window);

		// render
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		//绑定纹理
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, textureone);
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, texturetwo);


		ourShader.setFloat("mixValue", mixValue);

		
		glm::mat4 trans = glm::mat4(1.0f);
		//先平移后旋转
		//trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
		//trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));

		//先旋转后平移
		trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));
		trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
		unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");
		glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));


		ourShader.use();
		glBindVertexArray(VAO);
		glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);

		glfwSwapBuffers(window);
		glfwPollEvents();

	}

8. 绘制两个三角形,不同的显示方式

尝试再次调用glDrawElements画出第二个箱子,使用变换将其摆放在不同的位置。让这个箱子被摆放在窗口的左上角,并且会不断的缩放(而不是旋转)。(sin函数在这里会很有用,不过注意使用sin函数时应用负值会导致物体被翻转)。

	//5. 循环渲染
	while (!glfwWindowShouldClose(window)) {
		processInput(window);

		// render
		glClearColor(0.2f, 0.3f, 0.3f, 1.0f);
		glClear(GL_COLOR_BUFFER_BIT);
		//绑定纹理
		glActiveTexture(GL_TEXTURE0);
		glBindTexture(GL_TEXTURE_2D, textureone);
		glActiveTexture(GL_TEXTURE1);
		glBindTexture(GL_TEXTURE_2D, texturetwo);


		ourShader.setFloat("mixValue", mixValue);

		
		glm::mat4 trans = glm::mat4(1.0f);
		//先平移后旋转
		//trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
		//trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));

		//先旋转后平移
		trans = glm::rotate(trans, (float)glfwGetTime(), glm::vec3(0.0f, 0.0f, 1.0f));
		trans = glm::translate(trans, glm::vec3(0.5f, -0.5f, 0.0f));
		unsigned int transformLoc = glGetUniformLocation(ourShader.ID, "transform");
		glUniformMatrix4fv(transformLoc, 1, GL_FALSE, glm::value_ptr(trans));


		ourShader.use();
		glBindVertexArray(VAO);
		glDrawElements(GL_TRIANGLES,6,GL_UNSIGNED_INT,0);


		//second transformation
		trans = glm::mat4(1.0f);
		trans = glm::translate(trans, glm::vec3(-0.5f, 0.5f, 0.0f));
		float scaleAmount = static_cast<float>(sin(glfwGetTime()));
		trans = glm::scale(trans, glm::vec3(scaleAmount, scaleAmount, scaleAmount));
		glUniformMatrix4fv(transformLoc, 1, GL_FALSE, &trans[0][0]);// this time take the matrix value array's first element as its memory pointer value
		glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, 0);


		glfwSwapBuffers(window);
		glfwPollEvents();

	}

 

向量点乘与叉乘的概念及几何意义 - 知乎 (zhihu.com)

变换 - LearnOpenGL CN (learnopengl-cn.github.io)

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

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

相关文章

打开运行ps提示找不到msvcp140.dll的解决方法分享

最近&#xff0c;我在安装Adobe Photoshop&#xff08;简称PS&#xff09;和Adobe Premiere Pro&#xff08;简称PR&#xff09;时遇到了一个困扰我很久的问题&#xff0c;即提示找不到msvcp140.dll文件。msvcp140.dll是Microsoft Visual C 2015 Redistributable的一个组件&…

Crypto(7)BUUCTF-RSA4

BUUCTF RSA4 下载题目&#xff0c;可见文件给出了3组n和c N 331310324212000030020214312244232222400142410423413104441140203003243002104333214202031202212403400220031202142322434104143104244241214204444443323000244130122022422310201104411044030113302323014101…

2023-2024-1高级语言程序设计-一维数组

7-1 逆序输出数组元素的值 从键盘输入n个整数存入一维数组中&#xff0c;然后将数组元素的值逆序输出。 输入格式: 第一行输入整数个数n&#xff1b; 第二行输入n 个整数&#xff0c;数据之间以空格隔开。 输出格式: 逆序输出数组元素的值&#xff0c;每个数据之后跟一个空…

[LeetCode] 2.两数相加

一、题目描述 给你两个 非空 的链表&#xff0c;表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的&#xff0c;并且每个节点只能存储 一位 数字。 请你将两个数相加&#xff0c;并以相同形式返回一个表示和的链表。 你可以假设除了数字 0 之外&#xff0c;这两个…

火山引擎实时、低延时拥塞控制算法的优化实践

摘要 火山引擎智能拥塞控制算法 VICC&#xff08;Volcano Intelligent Congestion Control&#xff09;是一种自适应的拥塞控制算法&#xff0c;旨在解决全球不同网络环境下&#xff0c;不同音视频应用对带宽利用率和延时的差异化要求。它结合了传统拥塞控制算法&#xff08;如…

深度学习_4 数据训练之线性回归

训练数据 线性回归 基本原理 比如我们要买房&#xff0c;机器学习深度学习来预测房价。房价的影响因素有&#xff1a;卧室数量&#xff0c;卫生间数量&#xff0c;居住面积。此外&#xff0c;还需要加上偏差值来计算。我们要找到一个正确率高的计算方法来计算。 首先&#…

基于8086汽车智能小车控制系统

**单片机设计介绍&#xff0c;基于8086汽车智能小车控制系统 文章目录 一 概要二、功能设计设计思路 三、 软件设计原理图 五、 程序六、 文章目录 一 概要 基于 8086 的汽车智能小车控制系统是一种将微处理器技术应用于汽车控制的系统。下面是其主要的设计介绍&#xff1a; 硬…

Python库学习(十二):数据分析Pandas[下篇]

接着上篇《Python库学习(十一):数据分析Pandas[上篇]》,继续学习Pandas 1.数据过滤 在数据处理中&#xff0c;我们经常会对数据进行过滤&#xff0c;为此Pandas中提供mask()和where()两个函数&#xff1b; mask(): 在 满足条件的情况下替换数据&#xff0c;而不满足条件的部分…

在二维矩阵/数组中查找元素 Leetcode74, Leetcode240

这一类题型中二维数组的元素取值有序变化&#xff0c;因此可以用二分查找法。我们一起来看一下。 一、Leetcode 74 Leetcode 74. 搜索二维矩阵 这道题要在一个二维矩阵中查找元素。该二维矩阵有如下特点&#xff1a; 每行元素 从左到右 按非递减顺序排列。每行的第一个元素 …

JS+CSS随机点名详细介绍复制可用(可自己添加人名)

想必大家也想拥有一个可以随机点名的网页&#xff0c;接下来我为大家介绍一下随机点名&#xff0c;可用于抽人&#xff0c;哈哈 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style>* {margin: 0;…

麒麟系统查看磁盘UUID方法

通过查看 /dev/disk/by-uuid/ 目录下的软连接确定磁盘UUID ls -l /dev/disk/by-uuid/ 命令输出入下图所示&#xff0c;红框中即为磁盘UUID号 通过 blkid 命令查看系统中某块磁盘的uuid 号 blkid 命令输出如下图所示&#xff0c;UUID”” 中即为磁盘UUID号 开机自动…

记一次对某变异webshell的分析

0x01 前言 在某活动中捕获到一个变异的webshell&#xff08;jsp文件格式&#xff09;&#xff0c;如图1.1所示。样本webshell的大致功能是通过加载字节码来执行恶意代码&#xff0c;整个webshell的核心部分逻辑是在字节码中。 样本文件下载链接&#xff1a; https://github.co…

数据结构:AVL树讲解(C++)

AVL树 1.AVL树的概念2.平衡因子3.节点的定义4.插入操作5.旋转操作&#xff08;重点&#xff09;5.1左单旋5.2右单旋5.3左右双旋5.4右左双旋 6.一些简单的测试接口7.完整代码 1.AVL树的概念 普通二叉搜索树&#xff1a;二叉搜索树 二叉搜索树虽可以缩短查找的效率&#xff0c;但…

操作系统·操作系统引论

1.1 操作系统的目标和作用 1.目前常见操作系统&#xff1a; 微软&#xff1a;Windows系列&#xff08;以前MS-DOS&#xff09; UNIX&#xff1a;Solaris, AIX, HP UX, SVR4, BSD, ULTRIX 自由软件&#xff1a;Linux, freeBSD, Minix IBM: AIX, zOS(OS/390), OS/2, OS/400, PC…

壹[1],QT自定义控件创建(QtDesigner)

1&#xff0c;环境 Qt 5.14.2 VS2022 原因&#xff1a;厌烦了控件提升的繁琐设置&#xff0c;且看不到界面预览显示。 2&#xff0c;QT制作自定义控件 2.1&#xff0c;New/其他项目/Qt4 设计师自定义控件 2.2&#xff0c;设置项目名称 2.3&#xff0c;设置 2.4&#xff0c;设…

智能安全帽功能-EIS智能防抖摄像头4G定位视频语音气体检测

智能安全帽是一种集成多种智能功能的产品&#xff0c;例如实时定位、语音对讲、健康监测和AI智能预警等。这些丰富的功能能够更好地帮助工人开展工作&#xff0c;并提升安全保障水平。智能安全帽在各个行业中的应用越来越广泛。尤其在工程建设领域&#xff0c;项目管理和工作安…

京东店铺所有商品数据接口(JD.item_search_shop)

京东店铺所有商品数据接口是一种允许开发者在其应用程序中调用京东店铺所有商品数据的API接口。利用这一接口&#xff0c;开发者可以获取京东店铺的所有商品信息&#xff0c;包括商品标题、SKU信息、价格、优惠价、收藏数、销量、SKU图、标题、详情页图片等。 通过京东店铺所有…

嵌入式Linux和stm32区别? 之间有什么关系吗?

嵌入式Linux和stm32区别? 之间有什么关系吗&#xff1f; 主要体现在以下几个方面&#xff1a; 1.硬件资源不同 单片机一般是芯片内部集成flash、ram&#xff0c;ARM一般是CPU&#xff0c;配合外部的flash、ram、sd卡存储器使用。最近很多小伙伴找我&#xff0c;说想要一些嵌…

四阶龙格库塔与元胞自动机

龙格库塔法参考&#xff1a; 【精选】四阶龙格库塔算法及matlab代码_四阶龙格库塔法matlab_漫道长歌行的博客-CSDN博客 龙格库塔算法 Runge Kutta Method及其Matlab代码_龙格库塔法matlab_Lzh_023016的博客-CSDN博客 元胞自动机参考&#xff1a; 元胞自动机&#xff1a;森林…

小仙女必备,1分钟就能做出精美的电子相册

不知道大家有没有这样的困惑&#xff0c;手机里的照片太多&#xff0c;长久以来很多照片都容易被忘记。这个时候我们就可以将照片制作成电子相册&#xff0c;方便我们随时回味那些照片里的故事。如何制作呢&#xff1f; 制作电子相册只需要一个简单实用的制作工具就可以轻松完成…