OpenGL学习日记之模型绘制

news/2024/4/24 13:06:43/文章来源:https://blog.csdn.net/qq_36274965/article/details/129140143

自己编译运行过程中遇到的一些问题

下载Assimp已编译的lib(因为我们公司的电脑有很多权限和限制,也不能自己安装一些没有报备的软件,所以愁方便我就没有用cMake自己编译了)找到一位免费分享的博主的。
https://blog.csdn.net/lady_killer9/article/details/89429092

系统找不到zlib.dll文件的解决方法
https://blog.csdn.net/LHXvs2015/article/details/120674525
https://www.cnblogs.com/yangjinbang/p/8330786.html
在这里插入图片描述
下载Assimp可识别的模型地址
https://learnopengl-cn.github.io/03%20Model%20Loading/03%20Model/

现实生活中,我们都是美术同学通过一些现代的绘图工具,为我们导出模型来绘制,建模工具会自己生成所有的顶点坐标、顶点法线和纹理坐标,我们开发者就不需要去关注这些细节了。

Mesh

Mesh俗称网格,一个网格代表可绘制的实体。我们自定义一个网格类
至少要包含一组顶点数据,这组顶点数据应该包含顶点坐标,顶点法线,已经顶点的uv坐标。
一组绘制顺序索引,用于EBO绑定。
一组贴图数据,用于纹理映射。

#pragma once
// Std. Includes
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <vector>
using namespace std;
// GL Includes
#include <GL/glew.h> // Contains all the necessery OpenGL includes
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>struct Vertex {// Positionglm::vec3 Position;// Normalglm::vec3 Normal;// TexCoordsglm::vec2 TexCoords;
};struct Texture {GLuint id;string type;aiString path;
};class Mesh {
public:  vector<Vertex> vertices;vector<GLuint> indices;vector<Texture> textures;//构造函数Mesh(vector<Vertex> vertices, vector<GLuint> indices, vector<Texture> textures){this->vertices = vertices;this->indices = indices;this->textures = textures;// Now that we have all the required data, set the vertex buffers and its attribute pointers.this->setupMesh();}void Draw(Shader shader){       GLuint diffuseNr = 1;GLuint specularNr = 1; //绑定贴图与采样器for (GLuint i = 0; i < this->textures.size(); i++){glActiveTexture(GL_TEXTURE0 + i);        stringstream ss;string number;string name = this->textures[i].type;if (name == "texture_diffuse")ss << diffuseNr++; else if (name == "texture_specular")ss << specularNr++; number = ss.str(); //保证每个uniform采样器对应着正确的纹理单元glUniform1i(glGetUniformLocation(shader.Program, (name + number).c_str()), i);           glBindTexture(GL_TEXTURE_2D, this->textures[i].id);}glUniform1f(glGetUniformLocation(shader.Program, "material.shininess"), 16.0f);glBindVertexArray(this->VAO);glDrawElements(GL_TRIANGLES, this->indices.size(), GL_UNSIGNED_INT, 0);glBindVertexArray(0);for (GLuint i = 0; i < this->textures.size(); i++){glActiveTexture(GL_TEXTURE0 + i);glBindTexture(GL_TEXTURE_2D, 0);}}
private:  GLuint VAO, VBO, EBO;//初始化各种缓冲和链接数据void setupMesh(){//初始化VAO,VBO,EBO 缓冲对象glGenVertexArrays(1, &this->VAO);glGenBuffers(1, &this->VBO);glGenBuffers(1, &this->EBO);glBindVertexArray(this->VAO);//将顶点数据初始化至缓冲中glBindBuffer(GL_ARRAY_BUFFER, this->VBO);glBufferData(GL_ARRAY_BUFFER, this->vertices.size() * sizeof(Vertex), &this->vertices[0], GL_STATIC_DRAW);//将绘制顺序索引初始到缓冲中glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, this->EBO);glBufferData(GL_ELEMENT_ARRAY_BUFFER, this->indices.size() * sizeof(GLuint), &this->indices[0], GL_STATIC_DRAW);    glEnableVertexAttribArray(0);//将数据链接到顶点属性,告诉openGL如何解析这些数据glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)0);glEnableVertexAttribArray(1);glVertexAttribPointer(1, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, Normal));glEnableVertexAttribArray(2);glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*)offsetof(Vertex, TexCoords));glBindVertexArray(0);}
};

模型类

现实生活中一个我们看到的模型都是由很多部位组成的,也可以说成是由很多mesh组合而成的,比如一张桌子,是由一个桌板加四个桌脚拼成的为了方便抽象,我们又封装了一层模型的类。
这个类主要就是去解析美术给我们的一个从Blender,Maya等工具导出的模型,将其拆分为一个Mesh数组,然后再调用Mesh类的绘制。

#pragma once
// Std. Includes
#include <string>
#include <fstream>
#include <sstream>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
// GL Includes
#include <GL/glew.h> // Contains all the necessery OpenGL includes
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <SOIL.h>
#include <assimp/Importer.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>#include "Mesh.h"GLint TextureFromFile(const char* path, string directory);class Model
{
public:/*  Functions   */// Constructor, expects a filepath to a 3D model.Model(string path){this->loadModel(path);}// Draws the model, and thus all its meshesvoid Draw(Shader shader){for (GLuint i = 0; i < this->meshes.size(); i++)this->meshes[i].Draw(shader);}private:/*  Model Data  */vector<Mesh> meshes;string directory;vector<Texture> textures_loaded;	// Stores all the textures loaded so far, optimization to make sure textures aren't loaded more than once.int mycount = 0;void loadModel(string path){Assimp::Importer importer;const aiScene* scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs);     if (!scene || scene->mFlags == AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) // if is Not Zero{cout << "ERROR::ASSIMP:: " << importer.GetErrorString() << endl;return;}       this->directory = path.substr(0, path.find_last_of('/'));this->processNode(scene->mRootNode, scene);//printf("mesh个数: %d", mycount);}void processNode(aiNode* node, const aiScene* scene){for (GLuint i = 0; i < node->mNumMeshes; i++){           aiMesh* mesh = scene->mMeshes[node->mMeshes[i]];          this->meshes.push_back(this->processMesh(mesh, scene));}       for (GLuint i = 0; i < node->mNumChildren; i++){this->processNode(node->mChildren[i], scene);}}Mesh processMesh(aiMesh* mesh, const aiScene* scene){mycount++;vector<Vertex> vertices;vector<GLuint> indices;vector<Texture> textures;for (GLuint i = 0; i < mesh->mNumVertices; i++){Vertex vertex;glm::vec3 vector; vector.x = mesh->mVertices[i].x;vector.y = mesh->mVertices[i].y;vector.z = mesh->mVertices[i].z;vertex.Position = vector;vector.x = mesh->mNormals[i].x;vector.y = mesh->mNormals[i].y;vector.z = mesh->mNormals[i].z;vertex.Normal = vector;if (mesh->mTextureCoords[0]) {glm::vec2 vec;               vec.x = mesh->mTextureCoords[0][i].x;vec.y = mesh->mTextureCoords[0][i].y;vertex.TexCoords = vec;}elsevertex.TexCoords = glm::vec2(0.0f, 0.0f);vertices.push_back(vertex);}for (GLuint i = 0; i < mesh->mNumFaces; i++){aiFace face = mesh->mFaces[i];for (GLuint j = 0; j < face.mNumIndices; j++)indices.push_back(face.mIndices[j]);}if (mesh->mMaterialIndex >= 0){aiMaterial* material = scene->mMaterials[mesh->mMaterialIndex];            vector<Texture> diffuseMaps = this->loadMaterialTextures(material, aiTextureType_DIFFUSE, "texture_diffuse");textures.insert(textures.end(), diffuseMaps.begin(), diffuseMaps.end());vector<Texture> specularMaps = this->loadMaterialTextures(material, aiTextureType_SPECULAR, "texture_specular");textures.insert(textures.end(), specularMaps.begin(), specularMaps.end());}      return Mesh(vertices, indices, textures);}vector<Texture> loadMaterialTextures(aiMaterial* mat, aiTextureType type, string typeName){vector<Texture> textures;for (GLuint i = 0; i < mat->GetTextureCount(type); i++){aiString str;mat->GetTexture(type, i, &str);           GLboolean skip = false;for (GLuint j = 0; j < textures_loaded.size(); j++){if (std::strcmp(textures_loaded[j].path.C_Str(), str.C_Str()) == 0){textures.push_back(textures_loaded[j]);skip = true; break;}}if (!skip){  Texture texture;texture.id = TextureFromFile(str.C_Str(), this->directory);texture.type = typeName;texture.path = str;textures.push_back(texture);this->textures_loaded.push_back(texture); }}return textures;}
};GLint TextureFromFile(const char* path, string directory)
{  string filename = string(path);filename = directory + '/' + filename;GLuint textureID;glGenTextures(1, &textureID);int width, height;unsigned char* image = SOIL_load_image(filename.c_str(), &width, &height, 0, SOIL_LOAD_RGB);glBindTexture(GL_TEXTURE_2D, textureID);glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, GL_RGB, GL_UNSIGNED_BYTE, image);glGenerateMipmap(GL_TEXTURE_2D);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_MIPMAP_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);glBindTexture(GL_TEXTURE_2D, 0);SOIL_free_image_data(image);return textureID;
}

最后就是渲染代码


```cpp
// Std. Includes
#include <string>// GLEW
#define GLEW_STATIC
#include <GL/glew.h>// GLFW
#include <GLFW/glfw3.h>// GL includes
#include "Shader.h"
#include "Camera.h"
#include "Model.h"// GLM Mathemtics
#include <glm/glm.hpp>
#include <glm/gtc/matrix_transform.hpp>
#include <glm/gtc/type_ptr.hpp>// Other Libs
#include <SOIL.h>// Properties
GLuint screenWidth = 800, screenHeight = 600;// Function prototypes
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode);
void scroll_callback(GLFWwindow* window, double xoffset, double yoffset);
void mouse_callback(GLFWwindow* window, double xpos, double ypos);
void Do_Movement();const GLuint WIDTH = 800, HEIGHT = 600;
// Camera
glm::vec3 cameraPos = glm::vec3(0.0f, 0.0f, 3.0f);
glm::vec3 cameraFront = glm::vec3(0.0f, 0.0f, -1.0f);
glm::vec3 cameraUp = glm::vec3(0.0f, 1.0f, 0.0f);
GLfloat yaw = -90.0f;	// Yaw is initialized to -90.0 degrees since a yaw of 0.0 results in a direction vector pointing to the right (due to how Eular angles work) so we initially rotate a bit to the left.
GLfloat pitch = 0.0f;
GLfloat lastX = WIDTH / 2.0;
GLfloat lastY = HEIGHT / 2.0;
bool keys[1024];
bool firstMouse = true;GLfloat deltaTime = 0.0f;
GLfloat lastFrame = 0.0f;// The MAIN function, from here we start our application and run our Game loop
int main()
{// Init GLFWglfwInit();glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 3);glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);glfwWindowHint(GLFW_RESIZABLE, GL_FALSE);GLFWwindow* window = glfwCreateWindow(screenWidth, screenHeight, "LearnOpenGL", nullptr, nullptr); // WindowedglfwMakeContextCurrent(window);// Set the required callback functionsglfwSetKeyCallback(window, key_callback);glfwSetCursorPosCallback(window, mouse_callback);glfwSetScrollCallback(window, scroll_callback);// OptionsglfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);// Initialize GLEW to setup the OpenGL Function pointersglewExperimental = GL_TRUE;glewInit();// Define the viewport dimensionsglViewport(0, 0, screenWidth, screenHeight);// Setup some OpenGL optionsglEnable(GL_DEPTH_TEST);// Setup and compile our shadersShader shader("VertexShaderSource2_2_1.txt", "FragmentShaderSource2_2_1.txt");// Load modelsModel ourModel("nanosuit/nanosuit.obj");// Draw in wireframe//glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);// Game loopwhile (!glfwWindowShouldClose(window)){// Set frame timeGLfloat currentFrame = glfwGetTime();deltaTime = currentFrame - lastFrame;lastFrame = currentFrame;// Check and call eventsglfwPollEvents();Do_Movement();// Clear the colorbufferglClearColor(0.05f, 0.05f, 0.05f, 1.0f);glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);shader.Use();   // <-- Don't forget this one!// Transformation matricesglm::mat4 view(1);glm::mat4 projection(1);view = glm::lookAt(cameraPos, cameraPos + cameraFront, cameraUp);projection = glm::perspective(45.0f, (GLfloat)WIDTH / (GLfloat)HEIGHT, 0.1f, 100.0f);// Get the uniform locationsglUniformMatrix4fv(glGetUniformLocation(shader.Program, "projection"), 1, GL_FALSE, glm::value_ptr(projection));glUniformMatrix4fv(glGetUniformLocation(shader.Program, "view"), 1, GL_FALSE, glm::value_ptr(view));// Draw the loaded modelglm::mat4 model(1);model = glm::translate(model, glm::vec3(0.0f, -1.75f, 0.0f)); // Translate it down a bit so it's at the center of the scenemodel = glm::scale(model, glm::vec3(0.2f, 0.2f, 0.2f));	// It's a bit too big for our scene, so scale it downglUniformMatrix4fv(glGetUniformLocation(shader.Program, "model"), 1, GL_FALSE, glm::value_ptr(model));ourModel.Draw(shader);// Swap the buffersglfwSwapBuffers(window);}glfwTerminate();return 0;
}#pragma region "User input"// Moves/alters the camera positions based on user input
void Do_Movement()
{// Camera controlsGLfloat cameraSpeed = 5.0f * deltaTime;if (keys[GLFW_KEY_W])cameraPos += cameraSpeed * cameraFront;if (keys[GLFW_KEY_S])cameraPos -= cameraSpeed * cameraFront;if (keys[GLFW_KEY_A])cameraPos -= glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;if (keys[GLFW_KEY_D])cameraPos += glm::normalize(glm::cross(cameraFront, cameraUp)) * cameraSpeed;
}// Is called whenever a key is pressed/released via GLFW
void key_callback(GLFWwindow* window, int key, int scancode, int action, int mode)
{if (key == GLFW_KEY_ESCAPE && action == GLFW_PRESS)glfwSetWindowShouldClose(window, GL_TRUE);if (action == GLFW_PRESS)keys[key] = true;else if (action == GLFW_RELEASE)keys[key] = false;
}void mouse_callback(GLFWwindow* window, double xpos, double ypos)
{/*if (firstMouse)
{lastX = xpos;lastY = ypos;firstMouse = false;
}GLfloat xoffset = xpos - lastX;
GLfloat yoffset = lastY - ypos; // Reversed since y-coordinates go from bottom to left
lastX = xpos;
lastY = ypos;GLfloat sensitivity = 0.05;	// Change this value to your liking
xoffset *= sensitivity;
yoffset *= sensitivity;yaw += xoffset;
pitch += yoffset;// Make sure that when pitch is out of bounds, screen doesn't get flipped
if (pitch > 89.0f)pitch = 89.0f;
if (pitch < -89.0f)pitch = -89.0f;glm::vec3 front;
front.x = cos(glm::radians(yaw)) * cos(glm::radians(pitch));
front.y = sin(glm::radians(pitch));
front.z = sin(glm::radians(yaw)) * cos(glm::radians(pitch));
cameraFront = glm::normalize(front);*/
}void scroll_callback(GLFWwindow* window, double xoffset, double yoffset)
{}#pragma endregion

顶点着色器代码

#version 330 core
layout (location = 0) in vec3 position;
layout (location = 1) in vec3 normal;
layout (location = 2) in vec2 texCoords;out vec2 TexCoords;uniform mat4 model;
uniform mat4 view;
uniform mat4 projection;void main()
{gl_Position = projection * view * model * vec4(position, 1.0f);TexCoords = texCoords;
}

片段着色器代码

#version 330 corein vec2 TexCoords;out vec4 color;uniform sampler2D texture_diffuse1;void main()
{    color = vec4(texture(texture_diffuse1, TexCoords));
}

参考链接:https://learnopengl-cn.readthedocs.io/zh/latest/03%20Model%20Loading/03%20Model/

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

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

相关文章

【论文阅读】SCRFD: Sample and Computation 重分配的高效人脸检测

原始题目Sample and Computation Redistribution for Efficient Face Detection中文名称采样和计算 重分配的 高效人脸检测发表时间2021年5月10日平台ICLR-2022来源Imperial College&#xff0c; InsightFace文章链接https://arxiv.org/pdf/2105.04714.pdf开源代码官方实现&…

STM32开发(13)----获取唯一设备标识符UID

获取唯一设备标识符UID前言一、什么事UID二、实验过程1.CubeMx配置2.代码实现3.实验结果总结前言 这一章节介绍如何获取STM32芯片中的唯一的ID号的两种方法。 一、什么事UID 在许多项目中&#xff0c;识别设备是必要的。从简单的设备描述到更复杂的设备&#xff0c;如 USB 串…

uboot / linux添加/去除 版本号LOCALVERSION

背景 偶然的机会&#xff0c;在insmod驱动模块的时候&#xff0c;遇到报错&#xff1a; 查找原因&#xff0c;说是当前系统内核版本和模块编译使用版本不同&#xff01; 使用如下命令查看当前系统内核版本&#xff1a; uname -r 使用modinfo命令&#xff08;嵌入式设备没有此…

2022年中国前10电商GMV总结

我是卢松松&#xff0c;点点上面的头像&#xff0c;欢迎关注我哦&#xff01; 1&#xff0c;阿里8万亿;2&#xff0c;京东3万亿;3&#xff0c;拼多多3万亿;4&#xff0c;小程序私域电商3万亿;5&#xff0c;抖音电商1.4万亿。6&#xff0c;抖音本地生活服务电商600亿。7&#xf…

广东望京卡牌科技有限公司,2023年团建活动圆满举行

玉兔初临&#xff0c;春天相随&#xff0c;抖擞精神&#xff0c;好运连连。春天是一个万物复苏的季节&#xff0c;来自广东的望京卡牌科技有限公司&#xff0c;也迎来了新年第一次团建活动。在“乘风破浪、追逐梦想”的口号声中&#xff0c;2023望京卡牌目标启动会团结活动正式…

Fortinet推出新一代自研安全芯片,跨所有网络边缘加速网络与安全融合

专注网络与安全融合的全球网络安全领导者 Fortinet&#xff08;NASDAQ&#xff1a;FTNT&#xff09;&#xff0c;近日宣布推出新一代自研安全芯片 FortiSP5&#xff0c;作为 Fortinet ASIC 技术的最新突破&#xff0c;有力推动了分布式网络边缘安全的重大飞跃。FortiSP5 源自 F…

快鲸scrm发布快递行业私域运营解决方案

现如今&#xff0c;快递行业竞争格局日益激烈&#xff0c;前有“四通一达”等传统快递企业&#xff0c;后有自带互联网基因、绑定电商流量新贵快递企业&#xff0c;如菜鸟、京东等。在这一背景下&#xff0c;很多快递企业开启了增长破局之旅&#xff0c;他们纷纷搭建起私域运营…

0/1 nodes are available: 1 node(s) didn‘t match Pod‘s node affinity.

主要是需要确认你的yaml文件中是否有nodeSelector的配置&#xff0c;一般是因为k8s集群中没有相应的node节点匹配导致 这个错误消息表明您正在尝试在不符合Pod的节点亲和性规则的节点上运行Pod。这通常是由于节点选择器或节点亲和性规则设置不正确引起的。 以下是一些可能导致…

前端零基础入门-002-集成开发环境

本篇目标 了解市面上常用的前端集成开发环境&#xff08;ide&#xff09;掌握 HBuiberX 的使用&#xff1a;下载安装&#xff0c;新建项目、网页、运行网页。 内容摘要 本篇介绍了市面上流行的几款前端集成开发环境&#xff08;ide&#xff09;&#xff0c;并介绍了 Hbuilde…

微软Docker学习记录(第二单元)

文章目录什么是容器&#xff1f;什么是软件容器化&#xff1f;什么是 Docker&#xff1f;Docker 体系结构Docker 引擎Docker 客户端Docker 服务器Docker 对象原文链接&#xff1a; https://learn.microsoft.com/zh-cn/training/modules/intro-to-docker-containers以下原文部分…

Softing dataFEED OPC Suite Extended新版本支持从XML文件中读取生产数据

Softing dataFEED OPC Suite Extended V5.25的新功能——“文件读取&#xff08;File Read&#xff09;”&#xff0c;支持访问XML文件中可用的过程数据。 &#xff08;文件读取功能支持获取由XML文件提供的过程数据&#xff09;dataFEED OPC Suite Extended是用于OPC通信和云连…

技术干货!如何玩转Salesforce测试类 (Test Class)?

测试类主要用于评估其他代码片段&#xff0c;确保一切正常且可靠地运行。这可以作为一种早期预警系统&#xff0c;提醒开发人员出现了错误或问题。 不同类型的程序化测试 测试类可以分为多种不同的类型&#xff0c;这改变了我们编写测试的方式及其预期结果。对于Apex测试类&…

R语言实现可理解的随机森林模型(Random Forest)——iml包

Random Forest 解释模型1. 介绍2. 理解随机森林运行机理2.1导入需要的包2.2 构建随机森林模型2.3 RF特征重要性&#xff1a;2.4 特征对预测结果的影响2.5 交互作用2.6 替代模型&#xff08;Decision tree surrogate model&#xff09;2.71. 介绍 机器学习模型通常可以很好地进…

儿童袖套上架美国亚马逊CPC认证

袖套&#xff0c;也称套袖。是戴在袖管外的套子&#xff0c;旨在保护衣服的袖管。通常戴时松垂于另外一只衣袖外面的袖子。美国CPC认证简介&#xff1a;CPC认证是Children’s Product Certificate的英文简称&#xff0c;CPC证书就类似于国内的质检报告&#xff0c;在通过相关检…

内网渗透(四十五)之横向移动篇-WinRM远程执行命令横向移动

系列文章第一章节之基础知识篇 内网渗透(一)之基础知识-内网渗透介绍和概述 内网渗透(二)之基础知识-工作组介绍 内网渗透(三)之基础知识-域环境的介绍和优点 内网渗透(四)之基础知识-搭建域环境 内网渗透(五)之基础知识-Active Directory活动目录介绍和使用 内网渗透(六)之基…

PrivateLoader PPI服务发现RisePro恶意软件窃取分发信息

称为PrivateLoader的按安装付费&#xff08;PPI&#xff09;软件下载器服务正用于恶意软件RisePro的信息窃取。Flashpoint 于 2022 年 12月13日发现了新的窃取者&#xff0c;此前发现了在名为Russian Market的非法网络犯罪市场上使用该恶意软件泄露的“几组日志”。RisePro是一…

IDEA高效插件和设置

安装好Intellij idea之后&#xff0c;进行如下的初始化操作&#xff0c;工作效率提升十倍。 一. 安装插件 1. Codota 代码智能提示插件 只要打出首字母就能联想出一整条语句&#xff0c;这也太智能了&#xff0c;还显示了每条语句使用频率。 原因是它学习了我的项目代码&…

墨菲安全参与信息通信软件供应链安全社区成员大会并获自主研发创新成果奖

2023年2月16日&#xff0c;首届ICT软件供应链安全治理论坛暨信息通信软件供应链安全社区第二届成员大会在北京成功举办&#xff0c;多位业界顶级专家与工业和信息化部网络安全管理局相关领导出席&#xff0c;为现场观众分享了关于软件供应链可持续性与安全治理行业的前瞻与思考…

Apache Shiro与Spring Security对比

Apache Shiro VS Spring Security 1.Spring Security 官方文档&#xff1a;https://spring.io/projects/spring-security#overview介绍&#xff1a; Spring Security是一个能够为基于Spring的企业应用系统提供声明式的安全访问控制解决方案的安全框架。它提供了一组可以在Spr…

CAS底层原理及ABA问题

一、案例CAS是Java中Unsafe类里面的一个方法&#xff0c;它的全称是叫CompareAndSwap比较并交换的一个意思&#xff0c;它的主要功能是能够去保证在多线程的环境下对于共享变量修改的一个原子性。例如&#xff0c;比如说像这样一个场景&#xff0c;有一个成员变量state&#xf…